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 <algorithm> 8 #include <iterator> 9 #include <map> 10 #include <set> 11 #include <utility> 12 13 #include "base/command_line.h" 14 #include "base/memory/singleton.h" 15 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/utf_string_conversions.h" 17 #include "base/values.h" 18 #include "cc/base/switches.h" 19 #include "chrome/browser/flags_storage.h" 20 #include "chrome/common/chrome_content_client.h" 21 #include "chrome/common/chrome_switches.h" 22 #include "components/nacl/common/nacl_switches.h" 23 #include "content/public/browser/user_metrics.h" 24 #include "extensions/common/switches.h" 25 #include "grit/chromium_strings.h" 26 #include "grit/generated_resources.h" 27 #include "grit/google_chrome_strings.h" 28 #include "media/base/media_switches.h" 29 #include "ui/base/l10n/l10n_util.h" 30 #include "ui/base/ui_base_switches.h" 31 #include "ui/gfx/switches.h" 32 #include "ui/gl/gl_switches.h" 33 #include "ui/keyboard/keyboard_switches.h" 34 #include "ui/message_center/message_center_switches.h" 35 #include "ui/surface/surface_switches.h" 36 37 #if defined(USE_ASH) 38 #include "ash/ash_switches.h" 39 #endif 40 41 #if defined(OS_CHROMEOS) 42 #include "chromeos/chromeos_switches.h" 43 #include "third_party/cros_system_api/switches/chrome_switches.h" 44 #endif 45 46 using content::UserMetricsAction; 47 48 namespace about_flags { 49 50 // Macros to simplify specifying the type. 51 #define SINGLE_VALUE_TYPE_AND_VALUE(command_line_switch, switch_value) \ 52 Experiment::SINGLE_VALUE, \ 53 command_line_switch, switch_value, NULL, NULL, NULL, 0 54 #define SINGLE_VALUE_TYPE(command_line_switch) \ 55 SINGLE_VALUE_TYPE_AND_VALUE(command_line_switch, "") 56 #define ENABLE_DISABLE_VALUE_TYPE_AND_VALUE(enable_switch, enable_value, \ 57 disable_switch, disable_value) \ 58 Experiment::ENABLE_DISABLE_VALUE, enable_switch, enable_value, \ 59 disable_switch, disable_value, NULL, 3 60 #define ENABLE_DISABLE_VALUE_TYPE(enable_switch, disable_switch) \ 61 ENABLE_DISABLE_VALUE_TYPE_AND_VALUE(enable_switch, "", disable_switch, "") 62 #define MULTI_VALUE_TYPE(choices) \ 63 Experiment::MULTI_VALUE, NULL, NULL, NULL, NULL, choices, arraysize(choices) 64 65 namespace { 66 67 const unsigned kOsAll = kOsMac | kOsWin | kOsLinux | kOsCrOS | kOsAndroid; 68 const unsigned kOsDesktop = kOsMac | kOsWin | kOsLinux | kOsCrOS; 69 70 // Adds a |StringValue| to |list| for each platform where |bitmask| indicates 71 // whether the experiment is available on that platform. 72 void AddOsStrings(unsigned bitmask, ListValue* list) { 73 struct { 74 unsigned bit; 75 const char* const name; 76 } kBitsToOs[] = { 77 {kOsMac, "Mac"}, 78 {kOsWin, "Windows"}, 79 {kOsLinux, "Linux"}, 80 {kOsCrOS, "Chrome OS"}, 81 {kOsAndroid, "Android"}, 82 {kOsCrOSOwnerOnly, "Chrome OS (owner only)"}, 83 }; 84 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kBitsToOs); ++i) 85 if (bitmask & kBitsToOs[i].bit) 86 list->Append(new StringValue(kBitsToOs[i].name)); 87 } 88 89 // Convert switch constants to proper CommandLine::StringType strings. 90 CommandLine::StringType GetSwitchString(const std::string& flag) { 91 CommandLine cmd_line(CommandLine::NO_PROGRAM); 92 cmd_line.AppendSwitch(flag); 93 DCHECK(cmd_line.argv().size() == 2); 94 return cmd_line.argv()[1]; 95 } 96 97 // Scoops flags from a command line. 98 std::set<CommandLine::StringType> ExtractFlagsFromCommandLine( 99 const CommandLine& cmdline) { 100 std::set<CommandLine::StringType> flags; 101 // First do the ones between --flag-switches-begin and --flag-switches-end. 102 CommandLine::StringVector::const_iterator first = 103 std::find(cmdline.argv().begin(), cmdline.argv().end(), 104 GetSwitchString(switches::kFlagSwitchesBegin)); 105 CommandLine::StringVector::const_iterator last = 106 std::find(cmdline.argv().begin(), cmdline.argv().end(), 107 GetSwitchString(switches::kFlagSwitchesEnd)); 108 if (first != cmdline.argv().end() && last != cmdline.argv().end()) 109 flags.insert(first + 1, last); 110 #if defined(OS_CHROMEOS) 111 // Then add those between --policy-switches-begin and --policy-switches-end. 112 first = std::find(cmdline.argv().begin(), cmdline.argv().end(), 113 GetSwitchString(chromeos::switches::kPolicySwitchesBegin)); 114 last = std::find(cmdline.argv().begin(), cmdline.argv().end(), 115 GetSwitchString(chromeos::switches::kPolicySwitchesEnd)); 116 if (first != cmdline.argv().end() && last != cmdline.argv().end()) 117 flags.insert(first + 1, last); 118 #endif 119 return flags; 120 } 121 122 const Experiment::Choice kEnableCompositingForFixedPositionChoices[] = { 123 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 124 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 125 switches::kEnableCompositingForFixedPosition, ""}, 126 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 127 switches::kDisableCompositingForFixedPosition, ""}, 128 { IDS_FLAGS_COMPOSITING_FOR_FIXED_POSITION_HIGH_DPI, 129 switches::kEnableHighDpiCompositingForFixedPosition, ""} 130 }; 131 132 const Experiment::Choice kEnableCompositingForTransitionChoices[] = { 133 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 134 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 135 switches::kEnableCompositingForTransition, ""}, 136 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 137 switches::kDisableCompositingForTransition, ""}, 138 }; 139 140 const Experiment::Choice kEnableAcceleratedFixedRootBackgroundChoices[] = { 141 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 142 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 143 switches::kEnableAcceleratedFixedRootBackground, ""}, 144 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 145 switches::kDisableAcceleratedFixedRootBackground, ""}, 146 }; 147 148 const Experiment::Choice kGDIPresentChoices[] = { 149 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 150 { IDS_FLAGS_PRESENT_WITH_GDI_FIRST_SHOW, 151 switches::kDoFirstShowPresentWithGDI, ""}, 152 { IDS_FLAGS_PRESENT_WITH_GDI_ALL_SHOW, 153 switches::kDoAllShowPresentWithGDI, ""} 154 }; 155 156 const Experiment::Choice kTouchEventsChoices[] = { 157 { IDS_GENERIC_EXPERIMENT_CHOICE_AUTOMATIC, "", "" }, 158 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 159 switches::kTouchEvents, 160 switches::kTouchEventsEnabled }, 161 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 162 switches::kTouchEvents, 163 switches::kTouchEventsDisabled } 164 }; 165 166 const Experiment::Choice kTouchOptimizedUIChoices[] = { 167 { IDS_GENERIC_EXPERIMENT_CHOICE_AUTOMATIC, "", "" }, 168 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 169 switches::kTouchOptimizedUI, 170 switches::kTouchOptimizedUIEnabled }, 171 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 172 switches::kTouchOptimizedUI, 173 switches::kTouchOptimizedUIDisabled } 174 }; 175 176 const Experiment::Choice kNaClDebugMaskChoices[] = { 177 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 178 // Secure shell can be used on ChromeOS for forwarding the TCP port opened by 179 // debug stub to a remote machine. Since secure shell uses NaCl, we provide 180 // an option to switch off its debugging. 181 { IDS_NACL_DEBUG_MASK_CHOICE_EXCLUDE_UTILS, 182 switches::kNaClDebugMask, "!*://*/*ssh_client.nmf" }, 183 { IDS_NACL_DEBUG_MASK_CHOICE_INCLUDE_DEBUG, 184 switches::kNaClDebugMask, "*://*/*debug.nmf" } 185 }; 186 187 #if defined(OS_CHROMEOS) 188 189 const Experiment::Choice kChromeCaptivePortalDetectionChoices[] = { 190 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 191 { IDS_FLAGS_CHROME_CAPTIVE_PORTAL_DETECTOR, 192 chromeos::switches::kEnableChromeCaptivePortalDetector, "" }, 193 { IDS_FLAGS_SHILL_CAPTIVE_PORTAL_DETECTOR, 194 chromeos::switches::kDisableChromeCaptivePortalDetector, "" } 195 }; 196 197 #endif 198 199 const Experiment::Choice kImplSidePaintingChoices[] = { 200 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 201 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 202 cc::switches::kEnableImplSidePainting, ""}, 203 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 204 cc::switches::kDisableImplSidePainting, ""} 205 }; 206 207 const Experiment::Choice kDelegatedRendererChoices[] = { 208 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 209 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 210 switches::kEnableDelegatedRenderer, ""}, 211 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 212 switches::kDisableDelegatedRenderer, ""} 213 }; 214 215 const Experiment::Choice kMaxTilesForInterestAreaChoices[] = { 216 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 217 { IDS_FLAGS_MAX_TILES_FOR_INTEREST_AREA_SHORT, 218 cc::switches::kMaxTilesForInterestArea, "64"}, 219 { IDS_FLAGS_MAX_TILES_FOR_INTEREST_AREA_TALL, 220 cc::switches::kMaxTilesForInterestArea, "128"}, 221 { IDS_FLAGS_MAX_TILES_FOR_INTEREST_AREA_GRANDE, 222 cc::switches::kMaxTilesForInterestArea, "256"}, 223 { IDS_FLAGS_MAX_TILES_FOR_INTEREST_AREA_VENTI, 224 cc::switches::kMaxTilesForInterestArea, "512"} 225 }; 226 227 const Experiment::Choice kDefaultTileWidthChoices[] = { 228 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 229 { IDS_FLAGS_DEFAULT_TILE_WIDTH_SHORT, 230 switches::kDefaultTileWidth, "128"}, 231 { IDS_FLAGS_DEFAULT_TILE_WIDTH_TALL, 232 switches::kDefaultTileWidth, "256"}, 233 { IDS_FLAGS_DEFAULT_TILE_WIDTH_GRANDE, 234 switches::kDefaultTileWidth, "512"}, 235 { IDS_FLAGS_DEFAULT_TILE_WIDTH_VENTI, 236 switches::kDefaultTileWidth, "1024"} 237 }; 238 239 const Experiment::Choice kDefaultTileHeightChoices[] = { 240 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 241 { IDS_FLAGS_DEFAULT_TILE_HEIGHT_SHORT, 242 switches::kDefaultTileHeight, "128"}, 243 { IDS_FLAGS_DEFAULT_TILE_HEIGHT_TALL, 244 switches::kDefaultTileHeight, "256"}, 245 { IDS_FLAGS_DEFAULT_TILE_HEIGHT_GRANDE, 246 switches::kDefaultTileHeight, "512"}, 247 { IDS_FLAGS_DEFAULT_TILE_HEIGHT_VENTI, 248 switches::kDefaultTileHeight, "1024"} 249 }; 250 251 const Experiment::Choice kSimpleCacheBackendChoices[] = { 252 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 253 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 254 switches::kUseSimpleCacheBackend, "off" }, 255 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 256 switches::kUseSimpleCacheBackend, "on"} 257 }; 258 259 const Experiment::Choice kTabCaptureUpscaleQualityChoices[] = { 260 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 261 { IDS_FLAGS_TAB_CAPTURE_SCALE_QUALITY_FAST, 262 switches::kTabCaptureUpscaleQuality, "fast" }, 263 { IDS_FLAGS_TAB_CAPTURE_SCALE_QUALITY_GOOD, 264 switches::kTabCaptureUpscaleQuality, "good" }, 265 { IDS_FLAGS_TAB_CAPTURE_SCALE_QUALITY_BEST, 266 switches::kTabCaptureUpscaleQuality, "best" }, 267 }; 268 269 const Experiment::Choice kTabCaptureDownscaleQualityChoices[] = { 270 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 271 { IDS_FLAGS_TAB_CAPTURE_SCALE_QUALITY_FAST, 272 switches::kTabCaptureDownscaleQuality, "fast" }, 273 { IDS_FLAGS_TAB_CAPTURE_SCALE_QUALITY_GOOD, 274 switches::kTabCaptureDownscaleQuality, "good" }, 275 { IDS_FLAGS_TAB_CAPTURE_SCALE_QUALITY_BEST, 276 switches::kTabCaptureDownscaleQuality, "best" }, 277 }; 278 279 // RECORDING USER METRICS FOR FLAGS: 280 // ----------------------------------------------------------------------------- 281 // The first line of the experiment is the internal name. If you'd like to 282 // gather statistics about the usage of your flag, you should append a marker 283 // comment to the end of the feature name, like so: 284 // "my-special-feature", // FLAGS:RECORD_UMA 285 // 286 // After doing that, run //chrome/tools/extract_actions.py (see instructions at 287 // the top of that file for details) to update the chromeactions.txt file, which 288 // will enable UMA to record your feature flag. 289 // 290 // After your feature has shipped under a flag, you can locate the metrics under 291 // the action name AboutFlags_internal-action-name. Actions are recorded once 292 // per startup, so you should divide this number by AboutFlags_StartupTick to 293 // get a sense of usage. Note that this will not be the same as number of users 294 // with a given feature enabled because users can quit and relaunch the 295 // application multiple times over a given time interval. The dashboard also 296 // shows you how many (metrics reporting) users have enabled the flag over the 297 // last seven days. However, note that this is not the same as the number of 298 // users who have the flag enabled, since enabling the flag happens once, 299 // whereas running with the flag enabled happens until the user flips the flag 300 // again. 301 302 // To add a new experiment add to the end of kExperiments. There are two 303 // distinct types of experiments: 304 // . SINGLE_VALUE: experiment is either on or off. Use the SINGLE_VALUE_TYPE 305 // macro for this type supplying the command line to the macro. 306 // . MULTI_VALUE: a list of choices, the first of which should correspond to a 307 // deactivated state for this lab (i.e. no command line option). To specify 308 // this type of experiment use the macro MULTI_VALUE_TYPE supplying it the 309 // array of choices. 310 // See the documentation of Experiment for details on the fields. 311 // 312 // When adding a new choice, add it to the end of the list. 313 const Experiment kExperiments[] = { 314 { 315 "expose-for-tabs", // FLAGS:RECORD_UMA 316 IDS_FLAGS_TABPOSE_NAME, 317 IDS_FLAGS_TABPOSE_DESCRIPTION, 318 kOsMac, 319 #if defined(OS_MACOSX) 320 // The switch exists only on OS X. 321 SINGLE_VALUE_TYPE(switches::kEnableExposeForTabs) 322 #else 323 SINGLE_VALUE_TYPE("") 324 #endif 325 }, 326 { 327 "conflicting-modules-check", // FLAGS:RECORD_UMA 328 IDS_FLAGS_CONFLICTS_CHECK_NAME, 329 IDS_FLAGS_CONFLICTS_CHECK_DESCRIPTION, 330 kOsWin, 331 SINGLE_VALUE_TYPE(switches::kConflictingModulesCheck) 332 }, 333 { 334 "ignore-gpu-blacklist", 335 IDS_FLAGS_IGNORE_GPU_BLACKLIST_NAME, 336 IDS_FLAGS_IGNORE_GPU_BLACKLIST_DESCRIPTION, 337 kOsAll, 338 SINGLE_VALUE_TYPE(switches::kIgnoreGpuBlacklist) 339 }, 340 { 341 "force-compositing-mode-2", 342 IDS_FLAGS_FORCE_COMPOSITING_MODE_NAME, 343 IDS_FLAGS_FORCE_COMPOSITING_MODE_DESCRIPTION, 344 kOsMac | kOsWin | kOsLinux, 345 ENABLE_DISABLE_VALUE_TYPE(switches::kForceCompositingMode, 346 switches::kDisableForceCompositingMode) 347 }, 348 { 349 "threaded-compositing-mode", 350 IDS_FLAGS_THREADED_COMPOSITING_MODE_NAME, 351 IDS_FLAGS_THREADED_COMPOSITING_MODE_DESCRIPTION, 352 kOsMac | kOsWin | kOsLinux, 353 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableThreadedCompositing, 354 switches::kDisableThreadedCompositing) 355 }, 356 { 357 "force-accelerated-composited-scrolling", 358 IDS_FLAGS_FORCE_ACCELERATED_OVERFLOW_SCROLL_MODE_NAME, 359 IDS_FLAGS_FORCE_ACCELERATED_OVERFLOW_SCROLL_MODE_DESCRIPTION, 360 kOsAll, 361 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableAcceleratedOverflowScroll, 362 switches::kDisableAcceleratedOverflowScroll) 363 }, 364 { 365 "present-with-GDI", 366 IDS_FLAGS_PRESENT_WITH_GDI_NAME, 367 IDS_FLAGS_PRESENT_WITH_GDI_DESCRIPTION, 368 kOsWin, 369 MULTI_VALUE_TYPE(kGDIPresentChoices) 370 }, 371 { 372 "enable-experimental-canvas-features", 373 IDS_FLAGS_ENABLE_EXPERIMENTAL_CANVAS_FEATURES_NAME, 374 IDS_FLAGS_ENABLE_EXPERIMENTAL_CANVAS_FEATURES_DESCRIPTION, 375 kOsAll, 376 SINGLE_VALUE_TYPE(switches::kEnableExperimentalCanvasFeatures) 377 }, 378 { 379 "disable-accelerated-2d-canvas", 380 IDS_FLAGS_DISABLE_ACCELERATED_2D_CANVAS_NAME, 381 IDS_FLAGS_DISABLE_ACCELERATED_2D_CANVAS_DESCRIPTION, 382 kOsAll, 383 SINGLE_VALUE_TYPE(switches::kDisableAccelerated2dCanvas) 384 }, 385 { 386 "disable-threaded-animation", 387 IDS_FLAGS_DISABLE_THREADED_ANIMATION_NAME, 388 IDS_FLAGS_DISABLE_THREADED_ANIMATION_DESCRIPTION, 389 kOsAll, 390 SINGLE_VALUE_TYPE(cc::switches::kDisableThreadedAnimation) 391 }, 392 { 393 "composited-layer-borders", 394 IDS_FLAGS_COMPOSITED_LAYER_BORDERS, 395 IDS_FLAGS_COMPOSITED_LAYER_BORDERS_DESCRIPTION, 396 kOsAll, 397 SINGLE_VALUE_TYPE(cc::switches::kShowCompositedLayerBorders) 398 }, 399 { 400 "show-fps-counter", 401 IDS_FLAGS_SHOW_FPS_COUNTER, 402 IDS_FLAGS_SHOW_FPS_COUNTER_DESCRIPTION, 403 kOsAll, 404 SINGLE_VALUE_TYPE(cc::switches::kShowFPSCounter) 405 }, 406 { 407 "accelerated-filters", 408 IDS_FLAGS_ACCELERATED_FILTERS, 409 IDS_FLAGS_ACCELERATED_FILTERS_DESCRIPTION, 410 kOsAll, 411 SINGLE_VALUE_TYPE(switches::kEnableAcceleratedFilters) 412 }, 413 { 414 "disable-webgl", 415 IDS_FLAGS_DISABLE_WEBGL_NAME, 416 IDS_FLAGS_DISABLE_WEBGL_DESCRIPTION, 417 kOsAll, 418 SINGLE_VALUE_TYPE(switches::kDisableExperimentalWebGL) 419 }, 420 { 421 "disable-webrtc", 422 IDS_FLAGS_DISABLE_WEBRTC_NAME, 423 IDS_FLAGS_DISABLE_WEBRTC_DESCRIPTION, 424 kOsAndroid, 425 #if defined(OS_ANDROID) 426 SINGLE_VALUE_TYPE(switches::kDisableWebRTC) 427 #else 428 SINGLE_VALUE_TYPE("") 429 #endif 430 }, 431 #if defined(ENABLE_WEBRTC) 432 { 433 "enable-sctp-data-channels", 434 IDS_FLAGS_ENABLE_SCTP_DATA_CHANNELS_NAME, 435 IDS_FLAGS_ENABLE_SCTP_DATA_CHANNELS_DESCRIPTION, 436 kOsAll, 437 SINGLE_VALUE_TYPE(switches::kEnableSCTPDataChannels) 438 }, 439 { 440 "disable-device-enumeration", 441 IDS_FLAGS_DISABLE_DEVICE_ENUMERATION_NAME, 442 IDS_FLAGS_DISABLE_DEVICE_ENUMERATION_DESCRIPTION, 443 kOsAll, 444 SINGLE_VALUE_TYPE(switches::kDisableDeviceEnumeration) 445 }, 446 #endif 447 #if defined(OS_ANDROID) 448 { 449 "disable-webaudio", 450 IDS_FLAGS_DISABLE_WEBAUDIO_NAME, 451 IDS_FLAGS_DISABLE_WEBAUDIO_DESCRIPTION, 452 kOsAndroid, 453 SINGLE_VALUE_TYPE(switches::kDisableWebAudio) 454 }, 455 #endif 456 { 457 "fixed-position-creates-stacking-context", 458 IDS_FLAGS_FIXED_POSITION_CREATES_STACKING_CONTEXT_NAME, 459 IDS_FLAGS_FIXED_POSITION_CREATES_STACKING_CONTEXT_DESCRIPTION, 460 kOsAll, 461 ENABLE_DISABLE_VALUE_TYPE( 462 switches::kEnableFixedPositionCreatesStackingContext, 463 switches::kDisableFixedPositionCreatesStackingContext) 464 }, 465 { 466 "enable-compositing-for-fixed-position", 467 IDS_FLAGS_COMPOSITING_FOR_FIXED_POSITION_NAME, 468 IDS_FLAGS_COMPOSITING_FOR_FIXED_POSITION_DESCRIPTION, 469 kOsAll, 470 MULTI_VALUE_TYPE(kEnableCompositingForFixedPositionChoices) 471 }, 472 { 473 "enable-compositing-for-transition", 474 IDS_FLAGS_COMPOSITING_FOR_TRANSITION_NAME, 475 IDS_FLAGS_COMPOSITING_FOR_TRANSITION_DESCRIPTION, 476 kOsAll, 477 MULTI_VALUE_TYPE(kEnableCompositingForTransitionChoices) 478 }, 479 { 480 "enable-accelerated-fixed-root-background", 481 IDS_FLAGS_ACCELERATED_FIXED_ROOT_BACKGROUND_NAME, 482 IDS_FLAGS_ACCELERATED_FIXED_ROOT_BACKGROUND_DESCRIPTION, 483 kOsAll, 484 MULTI_VALUE_TYPE(kEnableAcceleratedFixedRootBackgroundChoices) 485 }, 486 // TODO(bbudge): When NaCl is on by default, remove this flag entry. 487 { 488 "enable-nacl", // FLAGS:RECORD_UMA 489 IDS_FLAGS_ENABLE_NACL_NAME, 490 IDS_FLAGS_ENABLE_NACL_DESCRIPTION, 491 kOsDesktop, 492 SINGLE_VALUE_TYPE(switches::kEnableNaCl) 493 }, 494 { 495 "enable-nacl-debug", // FLAGS:RECORD_UMA 496 IDS_FLAGS_ENABLE_NACL_DEBUG_NAME, 497 IDS_FLAGS_ENABLE_NACL_DEBUG_DESCRIPTION, 498 kOsDesktop, 499 SINGLE_VALUE_TYPE(switches::kEnableNaClDebug) 500 }, 501 { 502 "nacl-debug-mask", // FLAGS:RECORD_UMA 503 IDS_FLAGS_NACL_DEBUG_MASK_NAME, 504 IDS_FLAGS_NACL_DEBUG_MASK_DESCRIPTION, 505 kOsDesktop, 506 MULTI_VALUE_TYPE(kNaClDebugMaskChoices) 507 }, 508 { 509 "enable-pnacl", // FLAGS:RECORD_UMA 510 IDS_FLAGS_ENABLE_PNACL_NAME, 511 IDS_FLAGS_ENABLE_PNACL_DESCRIPTION, 512 kOsDesktop, 513 SINGLE_VALUE_TYPE(switches::kEnablePnacl) 514 }, 515 { 516 "extension-apis", // FLAGS:RECORD_UMA 517 IDS_FLAGS_EXPERIMENTAL_EXTENSION_APIS_NAME, 518 IDS_FLAGS_EXPERIMENTAL_EXTENSION_APIS_DESCRIPTION, 519 kOsDesktop, 520 SINGLE_VALUE_TYPE(extensions::switches::kEnableExperimentalExtensionApis) 521 }, 522 { 523 "extensions-on-chrome-urls", 524 IDS_FLAGS_EXTENSIONS_ON_CHROME_URLS_NAME, 525 IDS_FLAGS_EXTENSIONS_ON_CHROME_URLS_DESCRIPTION, 526 kOsAll, 527 SINGLE_VALUE_TYPE(extensions::switches::kExtensionsOnChromeURLs) 528 }, 529 { 530 "enable-fast-unload", 531 IDS_FLAGS_ENABLE_FAST_UNLOAD_NAME, 532 IDS_FLAGS_ENABLE_FAST_UNLOAD_DESCRIPTION, 533 kOsAll, 534 SINGLE_VALUE_TYPE(switches::kEnableFastUnload) 535 }, 536 { 537 "enable-adview", 538 IDS_FLAGS_ENABLE_ADVIEW_NAME, 539 IDS_FLAGS_ENABLE_ADVIEW_DESCRIPTION, 540 kOsDesktop, 541 SINGLE_VALUE_TYPE(switches::kEnableAdview) 542 }, 543 { 544 "enable-adview-src-attribute", 545 IDS_FLAGS_ENABLE_ADVIEW_SRC_ATTRIBUTE_NAME, 546 IDS_FLAGS_ENABLE_ADVIEW_SRC_ATTRIBUTE_DESCRIPTION, 547 kOsDesktop, 548 SINGLE_VALUE_TYPE(switches::kEnableAdviewSrcAttribute) 549 }, 550 { 551 "enable-app-window-controls", 552 IDS_FLAGS_ENABLE_APP_WINDOW_CONTROLS_NAME, 553 IDS_FLAGS_ENABLE_APP_WINDOW_CONTROLS_DESCRIPTION, 554 kOsDesktop, 555 SINGLE_VALUE_TYPE(switches::kEnableAppWindowControls) 556 }, 557 { 558 "script-badges", 559 IDS_FLAGS_SCRIPT_BADGES_NAME, 560 IDS_FLAGS_SCRIPT_BADGES_DESCRIPTION, 561 kOsDesktop, 562 SINGLE_VALUE_TYPE(switches::kScriptBadges) 563 }, 564 { 565 "script-bubble", 566 IDS_FLAGS_SCRIPT_BUBBLE_NAME, 567 IDS_FLAGS_SCRIPT_BUBBLE_DESCRIPTION, 568 kOsDesktop, 569 ENABLE_DISABLE_VALUE_TYPE_AND_VALUE(switches::kScriptBubble, "1", 570 switches::kScriptBubble, "0") 571 }, 572 { 573 "apps-new-install-bubble", 574 IDS_FLAGS_APPS_NEW_INSTALL_BUBBLE_NAME, 575 IDS_FLAGS_APPS_NEW_INSTALL_BUBBLE_DESCRIPTION, 576 kOsDesktop, 577 SINGLE_VALUE_TYPE(switches::kAppsNewInstallBubble) 578 }, 579 { 580 "disable-hyperlink-auditing", 581 IDS_FLAGS_DISABLE_HYPERLINK_AUDITING_NAME, 582 IDS_FLAGS_DISABLE_HYPERLINK_AUDITING_DESCRIPTION, 583 kOsAll, 584 SINGLE_VALUE_TYPE(switches::kNoPings) 585 }, 586 { 587 "experimental-location-features", // FLAGS:RECORD_UMA 588 IDS_FLAGS_EXPERIMENTAL_LOCATION_FEATURES_NAME, 589 IDS_FLAGS_EXPERIMENTAL_LOCATION_FEATURES_DESCRIPTION, 590 kOsMac, 591 SINGLE_VALUE_TYPE(switches::kExperimentalLocationFeatures) 592 }, 593 { 594 "tab-groups-context-menu", 595 IDS_FLAGS_TAB_GROUPS_CONTEXT_MENU_NAME, 596 IDS_FLAGS_TAB_GROUPS_CONTEXT_MENU_DESCRIPTION, 597 kOsWin, 598 SINGLE_VALUE_TYPE(switches::kEnableTabGroupsContextMenu) 599 }, 600 { 601 "enable-instant-extended-api", 602 IDS_FLAGS_ENABLE_INSTANT_EXTENDED_API, 603 IDS_FLAGS_ENABLE_INSTANT_EXTENDED_API_DESCRIPTION, 604 kOsMac | kOsWin | kOsCrOS, 605 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableInstantExtendedAPI, 606 switches::kDisableInstantExtendedAPI) 607 }, 608 { 609 "enable-local-first-load-ntp", 610 IDS_FLAGS_ENABLE_LOCAL_FIRST_LOAD_NTP, 611 IDS_FLAGS_ENABLE_LOCAL_FIRST_LOAD_NTP_DESCRIPTION, 612 kOsMac | kOsWin | kOsCrOS, 613 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableLocalFirstLoadNTP, 614 switches::kDisableLocalFirstLoadNTP) 615 }, 616 #if defined(OS_ANDROID) 617 { 618 "enable-new-ntp", 619 IDS_FLAGS_ENABLE_NEW_NTP, 620 IDS_FLAGS_ENABLE_NEW_NTP_DESCRIPTION, 621 kOsAndroid, 622 SINGLE_VALUE_TYPE(switches::kEnableNewNTP) 623 }, 624 #endif 625 { 626 "static-ip-config", 627 IDS_FLAGS_STATIC_IP_CONFIG_NAME, 628 IDS_FLAGS_STATIC_IP_CONFIG_DESCRIPTION, 629 kOsCrOS, 630 #if defined(OS_CHROMEOS) 631 // This switch exists only on Chrome OS. 632 SINGLE_VALUE_TYPE(chromeos::switches::kEnableStaticIPConfig) 633 #else 634 SINGLE_VALUE_TYPE("") 635 #endif 636 }, 637 { 638 "show-autofill-type-predictions", 639 IDS_FLAGS_SHOW_AUTOFILL_TYPE_PREDICTIONS_NAME, 640 IDS_FLAGS_SHOW_AUTOFILL_TYPE_PREDICTIONS_DESCRIPTION, 641 kOsAll, 642 SINGLE_VALUE_TYPE(autofill::switches::kShowAutofillTypePredictions) 643 }, 644 { 645 "enable-gesture-tap-highlight", 646 IDS_FLAGS_ENABLE_GESTURE_TAP_HIGHLIGHTING_NAME, 647 IDS_FLAGS_ENABLE_GESTURE_TAP_HIGHLIGHTING_DESCRIPTION, 648 kOsLinux | kOsCrOS, 649 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableGestureTapHighlight, 650 switches::kDisableGestureTapHighlight) 651 }, 652 { 653 "enable-smooth-scrolling", // FLAGS:RECORD_UMA 654 IDS_FLAGS_ENABLE_SMOOTH_SCROLLING_NAME, 655 IDS_FLAGS_ENABLE_SMOOTH_SCROLLING_DESCRIPTION, 656 // Can't expose the switch unless the code is compiled in. 657 // On by default for the Mac (different implementation in WebKit). 658 kOsWin | kOsLinux, 659 SINGLE_VALUE_TYPE(switches::kEnableSmoothScrolling) 660 }, 661 { 662 "enable-panels", 663 IDS_FLAGS_ENABLE_PANELS_NAME, 664 IDS_FLAGS_ENABLE_PANELS_DESCRIPTION, 665 kOsDesktop, 666 SINGLE_VALUE_TYPE(switches::kEnablePanels) 667 }, 668 { 669 // See http://crbug.com/120416 for how to remove this flag. 670 "save-page-as-mhtml", // FLAGS:RECORD_UMA 671 IDS_FLAGS_SAVE_PAGE_AS_MHTML_NAME, 672 IDS_FLAGS_SAVE_PAGE_AS_MHTML_DESCRIPTION, 673 kOsMac | kOsWin | kOsLinux, 674 SINGLE_VALUE_TYPE(switches::kSavePageAsMHTML) 675 }, 676 { 677 "enable-autologin", 678 IDS_FLAGS_ENABLE_AUTOLOGIN_NAME, 679 IDS_FLAGS_ENABLE_AUTOLOGIN_DESCRIPTION, 680 kOsMac | kOsWin | kOsLinux, 681 SINGLE_VALUE_TYPE(switches::kEnableAutologin) 682 }, 683 { 684 "enable-quic", 685 IDS_FLAGS_ENABLE_QUIC_NAME, 686 IDS_FLAGS_ENABLE_QUIC_DESCRIPTION, 687 kOsAll, 688 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableQuic, 689 switches::kDisableQuic) 690 }, 691 { 692 "enable-quic-https", 693 IDS_FLAGS_ENABLE_QUIC_HTTPS_NAME, 694 IDS_FLAGS_ENABLE_QUIC_HTTPS_DESCRIPTION, 695 kOsAll, 696 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableQuicHttps, 697 switches::kDisableQuicHttps) 698 }, 699 { 700 "enable-spdy4a2", 701 IDS_FLAGS_ENABLE_SPDY4A2_NAME, 702 IDS_FLAGS_ENABLE_SPDY4A2_DESCRIPTION, 703 kOsAll, 704 SINGLE_VALUE_TYPE(switches::kEnableSpdy4a2) 705 }, 706 { 707 "enable-http2-draft-04", 708 IDS_FLAGS_ENABLE_HTTP2_DRAFT_04_NAME, 709 IDS_FLAGS_ENABLE_HTTP2_DRAFT_04_DESCRIPTION, 710 kOsAll, 711 SINGLE_VALUE_TYPE(switches::kEnableHttp2Draft04) 712 }, 713 { 714 "enable-async-dns", 715 IDS_FLAGS_ENABLE_ASYNC_DNS_NAME, 716 IDS_FLAGS_ENABLE_ASYNC_DNS_DESCRIPTION, 717 kOsWin | kOsMac | kOsLinux | kOsCrOS, 718 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableAsyncDns, 719 switches::kDisableAsyncDns) 720 }, 721 { 722 "disable-media-source", 723 IDS_FLAGS_DISABLE_WEBKIT_MEDIA_SOURCE_NAME, 724 IDS_FLAGS_DISABLE_WEBKIT_MEDIA_SOURCE_DESCRIPTION, 725 kOsAll, 726 SINGLE_VALUE_TYPE(switches::kDisableWebKitMediaSource) 727 }, 728 { 729 "enable-encrypted-media", 730 IDS_FLAGS_ENABLE_ENCRYPTED_MEDIA_NAME, 731 IDS_FLAGS_ENABLE_ENCRYPTED_MEDIA_DESCRIPTION, 732 kOsAll, 733 SINGLE_VALUE_TYPE(switches::kEnableEncryptedMedia) 734 }, 735 { 736 "disable-encrypted-media", 737 IDS_FLAGS_DISABLE_PREFIXED_ENCRYPTED_MEDIA_NAME, 738 IDS_FLAGS_DISABLE_PREFIXED_ENCRYPTED_MEDIA_DESCRIPTION, 739 kOsAll, 740 SINGLE_VALUE_TYPE(switches::kDisableLegacyEncryptedMedia) 741 }, 742 { 743 "override-encrypted-media-canplaytype", 744 IDS_FLAGS_ENCRYPTED_MEDIA_CANPLAYTYPE_OVERRIDE_NAME, 745 IDS_FLAGS_ENCRYPTED_MEDIA_CANPLAYTYPE_OVERRIDE_DESCRIPTION, 746 kOsMac | kOsWin, 747 SINGLE_VALUE_TYPE(switches::kOverrideEncryptedMediaCanPlayType) 748 }, 749 { 750 "enable-opus-playback", 751 IDS_FLAGS_ENABLE_OPUS_PLAYBACK_NAME, 752 IDS_FLAGS_ENABLE_OPUS_PLAYBACK_DESCRIPTION, 753 kOsDesktop, 754 SINGLE_VALUE_TYPE(switches::kEnableOpusPlayback) 755 }, 756 { 757 "enable-vp8-alpha-playback", 758 IDS_FLAGS_ENABLE_VP8_ALPHA_PLAYBACK_NAME, 759 IDS_FLAGS_ENABLE_VP8_ALPHA_PLAYBACK_DESCRIPTION, 760 kOsDesktop, 761 SINGLE_VALUE_TYPE(switches::kEnableVp8AlphaPlayback) 762 }, 763 { 764 "enable-managed-users", 765 IDS_FLAGS_ENABLE_LOCALLY_MANAGED_USERS_NAME, 766 IDS_FLAGS_ENABLE_LOCALLY_MANAGED_USERS_DESCRIPTION, 767 kOsMac | kOsWin | kOsLinux | kOsCrOSOwnerOnly, 768 SINGLE_VALUE_TYPE(switches::kEnableManagedUsers) 769 }, 770 #if defined(USE_ASH) 771 { 772 "ash-disable-auto-maximizing", 773 IDS_FLAGS_ASH_AUTO_MAXIMIZING_NAME, 774 IDS_FLAGS_ASH_AUTO_MAXIMIZING_DESCRIPTION, 775 kOsWin | kOsLinux | kOsCrOS, 776 SINGLE_VALUE_TYPE(ash::switches::kAshDisableAutoMaximizing) 777 }, 778 { 779 "ash-disable-auto-window-placement", 780 IDS_FLAGS_ASH_AUTO_WINDOW_PLACEMENT_NAME, 781 IDS_FLAGS_ASH_AUTO_WINDOW_PLACEMENT_DESCRIPTION, 782 kOsWin | kOsLinux | kOsCrOS, 783 SINGLE_VALUE_TYPE(ash::switches::kAshDisableAutoWindowPlacement) 784 }, 785 { 786 "ash-disable-per-app-launcher", 787 IDS_FLAGS_ASH_DISABLE_PER_APP_LAUNCHER_NAME, 788 IDS_FLAGS_ASH_DISABLE_PER_APP_LAUNCHER_DESCRIPTION, 789 kOsWin | kOsLinux | kOsCrOS, 790 SINGLE_VALUE_TYPE(ash::switches::kAshDisablePerAppLauncher) 791 }, 792 #endif 793 { 794 "per-tile-painting", 795 IDS_FLAGS_PER_TILE_PAINTING_NAME, 796 IDS_FLAGS_PER_TILE_PAINTING_DESCRIPTION, 797 kOsMac | kOsLinux | kOsCrOS, 798 SINGLE_VALUE_TYPE(cc::switches::kEnablePerTilePainting) 799 }, 800 { 801 "enable-javascript-harmony", 802 IDS_FLAGS_ENABLE_JAVASCRIPT_HARMONY_NAME, 803 IDS_FLAGS_ENABLE_JAVASCRIPT_HARMONY_DESCRIPTION, 804 kOsAll, 805 SINGLE_VALUE_TYPE_AND_VALUE(switches::kJavaScriptFlags, "--harmony") 806 }, 807 { 808 "enable-tab-browser-dragging", 809 IDS_FLAGS_ENABLE_TAB_BROWSER_DRAGGING_NAME, 810 IDS_FLAGS_ENABLE_TAB_BROWSER_DRAGGING_DESCRIPTION, 811 kOsWin, 812 SINGLE_VALUE_TYPE(switches::kTabBrowserDragging) 813 }, 814 { 815 "disable-restore-session-state", 816 IDS_FLAGS_DISABLE_RESTORE_SESSION_STATE_NAME, 817 IDS_FLAGS_DISABLE_RESTORE_SESSION_STATE_DESCRIPTION, 818 kOsAll, 819 SINGLE_VALUE_TYPE(switches::kDisableRestoreSessionState) 820 }, 821 { 822 "disable-software-rasterizer", 823 IDS_FLAGS_DISABLE_SOFTWARE_RASTERIZER_NAME, 824 IDS_FLAGS_DISABLE_SOFTWARE_RASTERIZER_DESCRIPTION, 825 #if defined(ENABLE_SWIFTSHADER) 826 kOsAll, 827 #else 828 0, 829 #endif 830 SINGLE_VALUE_TYPE(switches::kDisableSoftwareRasterizer) 831 }, 832 { 833 "enable-experimental-web-platform-features", 834 IDS_FLAGS_EXPERIMENTAL_WEB_PLATFORM_FEATURES_NAME, 835 IDS_FLAGS_EXPERIMENTAL_WEB_PLATFORM_FEATURES_DESCRIPTION, 836 kOsAll, 837 SINGLE_VALUE_TYPE(switches::kEnableExperimentalWebPlatformFeatures) 838 }, 839 { 840 "enable-css-shaders", 841 IDS_FLAGS_CSS_SHADERS_NAME, 842 IDS_FLAGS_CSS_SHADERS_DESCRIPTION, 843 kOsAll, 844 SINGLE_VALUE_TYPE(switches::kEnableCssShaders) 845 }, 846 { 847 "disable-ntp-other-sessions-menu", 848 IDS_FLAGS_NTP_OTHER_SESSIONS_MENU_NAME, 849 IDS_FLAGS_NTP_OTHER_SESSIONS_MENU_DESCRIPTION, 850 kOsDesktop, 851 SINGLE_VALUE_TYPE(switches::kDisableNTPOtherSessionsMenu) 852 }, 853 #if defined(USE_ASH) 854 { 855 "enable-ash-oak", 856 IDS_FLAGS_ENABLE_ASH_OAK_NAME, 857 IDS_FLAGS_ENABLE_ASH_OAK_DESCRIPTION, 858 kOsAll, 859 SINGLE_VALUE_TYPE(ash::switches::kAshEnableOak), 860 }, 861 #endif 862 { 863 "enable-devtools-experiments", 864 IDS_FLAGS_ENABLE_DEVTOOLS_EXPERIMENTS_NAME, 865 IDS_FLAGS_ENABLE_DEVTOOLS_EXPERIMENTS_DESCRIPTION, 866 kOsDesktop, 867 SINGLE_VALUE_TYPE(switches::kEnableDevToolsExperiments) 868 }, 869 { 870 "remote-debugging-raw-usb", 871 IDS_FLAGS_REMOTE_DEBUGGING_RAW_USB_NAME, 872 IDS_FLAGS_REMOTE_DEBUGGING_RAW_USB_DESCRIPTION, 873 kOsDesktop, 874 SINGLE_VALUE_TYPE(switches::kRemoteDebuggingRawUSB) 875 }, 876 { 877 "silent-debugger-extension-api", 878 IDS_FLAGS_SILENT_DEBUGGER_EXTENSION_API_NAME, 879 IDS_FLAGS_SILENT_DEBUGGER_EXTENSION_API_DESCRIPTION, 880 kOsDesktop, 881 SINGLE_VALUE_TYPE(switches::kSilentDebuggerExtensionAPI) 882 }, 883 { 884 "enable-suggestions-ntp", 885 IDS_FLAGS_NTP_SUGGESTIONS_PAGE_NAME, 886 IDS_FLAGS_NTP_SUGGESTIONS_PAGE_DESCRIPTION, 887 kOsDesktop, 888 SINGLE_VALUE_TYPE(switches::kEnableSuggestionsTabPage) 889 }, 890 { 891 "spellcheck-autocorrect", 892 IDS_FLAGS_SPELLCHECK_AUTOCORRECT, 893 IDS_FLAGS_SPELLCHECK_AUTOCORRECT_DESCRIPTION, 894 kOsWin | kOsLinux | kOsCrOS, 895 SINGLE_VALUE_TYPE(switches::kEnableSpellingAutoCorrect) 896 }, 897 { 898 "enable-scroll-prediction", 899 IDS_FLAGS_ENABLE_SCROLL_PREDICTION_NAME, 900 IDS_FLAGS_ENABLE_SCROLL_PREDICTION_DESCRIPTION, 901 kOsDesktop, 902 SINGLE_VALUE_TYPE(switches::kEnableScrollPrediction) 903 }, 904 { 905 "touch-events", 906 IDS_TOUCH_EVENTS_NAME, 907 IDS_TOUCH_EVENTS_DESCRIPTION, 908 kOsDesktop, 909 MULTI_VALUE_TYPE(kTouchEventsChoices) 910 }, 911 { 912 "touch-optimized-ui", 913 IDS_FLAGS_TOUCH_OPTIMIZED_UI_NAME, 914 IDS_FLAGS_TOUCH_OPTIMIZED_UI_DESCRIPTION, 915 kOsWin, 916 MULTI_VALUE_TYPE(kTouchOptimizedUIChoices) 917 }, 918 { 919 "disable-touch-adjustment", 920 IDS_DISABLE_TOUCH_ADJUSTMENT_NAME, 921 IDS_DISABLE_TOUCH_ADJUSTMENT_DESCRIPTION, 922 kOsWin | kOsLinux | kOsCrOS, 923 SINGLE_VALUE_TYPE(switches::kDisableTouchAdjustment) 924 }, 925 #if defined(OS_CHROMEOS) 926 { 927 "ash-use-alternate-shelf", 928 IDS_FLAGS_ALTERNATE_SHELF_LAYOUT_NAME, 929 IDS_FLAGS_ALTERNATE_SHELF_LAYOUT_DESCRIPTION, 930 kOsCrOS, 931 SINGLE_VALUE_TYPE(ash::switches::kAshUseAlternateShelfLayout) 932 }, 933 { 934 "enable-background-loader", 935 IDS_ENABLE_BACKLOADER_NAME, 936 IDS_ENABLE_BACKLOADER_DESCRIPTION, 937 kOsCrOS, 938 SINGLE_VALUE_TYPE(chromeos::switches::kEnableBackgroundLoader) 939 }, 940 { 941 "enable-screensaver-extension", 942 IDS_ENABLE_SCREENSAVER_EXTENSION_NAME, 943 IDS_ENABLE_SCREENSAVER_EXTENSION_DESCRIPTION, 944 kOsCrOS, 945 SINGLE_VALUE_TYPE(chromeos::switches::kEnableScreensaverExtensions) 946 }, 947 { 948 "no-discard-tabs", 949 IDS_FLAGS_NO_DISCARD_TABS_NAME, 950 IDS_FLAGS_NO_DISCARD_TABS_DESCRIPTION, 951 kOsCrOS, 952 SINGLE_VALUE_TYPE(chromeos::switches::kNoDiscardTabs) 953 }, 954 { 955 "ash-enable-docked-windows", 956 IDS_FLAGS_DOCKED_WINDOWS_NAME, 957 IDS_FLAGS_DOCKED_WINDOWS_DESCRIPTION, 958 kOsCrOS, 959 SINGLE_VALUE_TYPE(ash::switches::kAshEnableDockedWindows) 960 }, 961 #endif 962 { 963 "enable-download-resumption", 964 IDS_FLAGS_ENABLE_DOWNLOAD_RESUMPTION_NAME, 965 IDS_FLAGS_ENABLE_DOWNLOAD_RESUMPTION_DESCRIPTION, 966 kOsDesktop, 967 SINGLE_VALUE_TYPE(switches::kEnableDownloadResumption) 968 }, 969 { 970 "allow-nacl-socket-api", 971 IDS_FLAGS_ALLOW_NACL_SOCKET_API_NAME, 972 IDS_FLAGS_ALLOW_NACL_SOCKET_API_DESCRIPTION, 973 kOsDesktop, 974 SINGLE_VALUE_TYPE_AND_VALUE(switches::kAllowNaClSocketAPI, "*") 975 }, 976 { 977 "stacked-tab-strip", 978 IDS_FLAGS_STACKED_TAB_STRIP_NAME, 979 IDS_FLAGS_STACKED_TAB_STRIP_DESCRIPTION, 980 kOsWin, 981 SINGLE_VALUE_TYPE(switches::kEnableStackedTabStrip) 982 }, 983 { 984 "force-device-scale-factor", 985 IDS_FLAGS_FORCE_HIGH_DPI_NAME, 986 IDS_FLAGS_FORCE_HIGH_DPI_DESCRIPTION, 987 kOsCrOS, 988 SINGLE_VALUE_TYPE_AND_VALUE(switches::kForceDeviceScaleFactor, "2") 989 }, 990 #if defined(OS_CHROMEOS) 991 { 992 "allow-touchpad-three-finger-click", 993 IDS_FLAGS_ALLOW_TOUCHPAD_THREE_FINGER_CLICK_NAME, 994 IDS_FLAGS_ALLOW_TOUCHPAD_THREE_FINGER_CLICK_DESCRIPTION, 995 kOsCrOS, 996 SINGLE_VALUE_TYPE(chromeos::switches::kEnableTouchpadThreeFingerClick) 997 }, 998 #endif 999 #if defined(USE_ASH) 1000 { 1001 "show-launcher-alignment-menu", 1002 IDS_FLAGS_SHOW_SHELF_ALIGNMENT_MENU_NAME, 1003 IDS_FLAGS_SHOW_SHELF_ALIGNMENT_MENU_DESCRIPTION, 1004 kOsAll, 1005 SINGLE_VALUE_TYPE(switches::kShowShelfAlignmentMenu) 1006 }, 1007 { 1008 "disable-minimize-on-second-launcher-item-click", 1009 IDS_FLAGS_DISABLE_MINIMIZE_ON_SECOND_LAUNCHER_ITEM_CLICK_NAME, 1010 IDS_FLAGS_DISABLE_MINIMIZE_ON_SECOND_LAUNCHER_ITEM_CLICK_DESCRIPTION, 1011 kOsAll, 1012 SINGLE_VALUE_TYPE(switches::kDisableMinimizeOnSecondLauncherItemClick) 1013 }, 1014 { 1015 "enable-overview-mode", 1016 IDS_FLAGS_OVERVIEW_MODE_NAME, 1017 IDS_FLAGS_OVERVIEW_MODE_DESCRIPTION, 1018 kOsCrOS, 1019 SINGLE_VALUE_TYPE(ash::switches::kAshEnableOverviewMode) 1020 }, 1021 { 1022 "show-touch-hud", 1023 IDS_FLAGS_SHOW_TOUCH_HUD_NAME, 1024 IDS_FLAGS_SHOW_TOUCH_HUD_DESCRIPTION, 1025 kOsAll, 1026 SINGLE_VALUE_TYPE(ash::switches::kAshTouchHud) 1027 }, 1028 { 1029 "enable-pinch", 1030 IDS_FLAGS_ENABLE_PINCH_SCALE_NAME, 1031 IDS_FLAGS_ENABLE_PINCH_SCALE_DESCRIPTION, 1032 kOsLinux | kOsWin | kOsCrOS, 1033 ENABLE_DISABLE_VALUE_TYPE(switches::kEnablePinch, switches::kDisablePinch), 1034 }, 1035 { 1036 "enable-pinch-virtual-viewport", 1037 IDS_FLAGS_ENABLE_PINCH_VIRTUAL_VIEWPORT_NAME, 1038 IDS_FLAGS_ENABLE_PINCH_VIRTUAL_VIEWPORT_DESCRIPTION, 1039 kOsLinux | kOsWin | kOsCrOS, 1040 SINGLE_VALUE_TYPE(cc::switches::kEnablePinchVirtualViewport), 1041 }, 1042 { 1043 "forced-maximize-mode", 1044 IDS_FLAGS_FORCE_MAXIMIZE_MODE_NAME, 1045 IDS_FLAGS_FORCE_MAXIMIZE_MODE_DESCRIPTION, 1046 kOsLinux | kOsWin | kOsCrOS, 1047 SINGLE_VALUE_TYPE(ash::switches::kForcedMaximizeMode), 1048 }, 1049 #endif // defined(USE_ASH) 1050 #if defined(OS_CHROMEOS) 1051 { 1052 "disable-boot-animation", 1053 IDS_FLAGS_DISABLE_BOOT_ANIMATION, 1054 IDS_FLAGS_DISABLE_BOOT_ANIMATION_DESCRIPTION, 1055 kOsCrOSOwnerOnly, 1056 SINGLE_VALUE_TYPE(chromeos::switches::kDisableBootAnimation), 1057 }, 1058 { 1059 "captive-portal-detector", 1060 IDS_FLAGS_CAPTIVE_PORTAL_DETECTOR_NAME, 1061 IDS_FLAGS_CAPTIVE_PORTAL_DETECTOR_DESCRIPTION, 1062 kOsCrOSOwnerOnly, 1063 MULTI_VALUE_TYPE(kChromeCaptivePortalDetectionChoices), 1064 }, 1065 { 1066 "disable-new-lock-animations", 1067 IDS_FLAGS_ASH_NEW_LOCK_ANIMATIONS, 1068 IDS_FLAGS_ASH_NEW_LOCK_ANIMATIONS_DESCRIPTION, 1069 kOsCrOS, 1070 SINGLE_VALUE_TYPE(ash::switches::kAshDisableNewLockAnimations), 1071 }, 1072 { 1073 "file-manager-show-checkboxes", 1074 IDS_FLAGS_FILE_MANAGER_SHOW_CHECKBOXES_NAME, 1075 IDS_FLAGS_FILE_MANAGER_SHOW_CHECKBOXES_DESCRIPTION, 1076 kOsCrOS, 1077 SINGLE_VALUE_TYPE(chromeos::switches::kFileManagerShowCheckboxes) 1078 }, 1079 { 1080 "file-manager-enable-webstore-integration", 1081 IDS_FLAGS_FILE_MANAGER_ENABLE_WEBSTORE_INTEGRATION, 1082 IDS_FLAGS_FILE_MANAGER_ENABLE_WEBSTORE_INTEGRATION_DESCRIPTION, 1083 kOsCrOS, 1084 SINGLE_VALUE_TYPE(chromeos::switches::kFileManagerEnableWebstoreIntegration) 1085 }, 1086 { 1087 "disable-quickoffice-component-app", 1088 IDS_FLAGS_DISABLE_QUICKOFFICE_COMPONENT_APP_NAME, 1089 IDS_FLAGS_DISABLE_QUICKOFFICE_COMPONENT_APP_DESCRIPTION, 1090 kOsCrOS, 1091 SINGLE_VALUE_TYPE(chromeos::switches::kDisableQuickofficeComponentApp), 1092 }, 1093 #endif // defined(OS_CHROMEOS) 1094 { 1095 "views-textfield", 1096 IDS_FLAGS_VIEWS_TEXTFIELD_NAME, 1097 IDS_FLAGS_VIEWS_TEXTFIELD_DESCRIPTION, 1098 kOsWin, 1099 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableViewsTextfield, 1100 switches::kDisableViewsTextfield), 1101 }, 1102 { 1103 "new-dialog-style", 1104 IDS_FLAGS_NEW_DIALOG_STYLE_NAME, 1105 IDS_FLAGS_NEW_DIALOG_STYLE_DESCRIPTION, 1106 kOsWin | kOsCrOS, 1107 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableNewDialogStyle, 1108 switches::kDisableNewDialogStyle), 1109 }, 1110 { "disable-accelerated-video-decode", 1111 IDS_FLAGS_DISABLE_ACCELERATED_VIDEO_DECODE_NAME, 1112 IDS_FLAGS_DISABLE_ACCELERATED_VIDEO_DECODE_DESCRIPTION, 1113 kOsWin | kOsCrOS, 1114 SINGLE_VALUE_TYPE(switches::kDisableAcceleratedVideoDecode), 1115 }, 1116 #if defined(USE_ASH) 1117 { 1118 "ash-debug-shortcuts", 1119 IDS_FLAGS_DEBUG_SHORTCUTS_NAME, 1120 IDS_FLAGS_DEBUG_SHORTCUTS_DESCRIPTION, 1121 kOsAll, 1122 SINGLE_VALUE_TYPE(ash::switches::kAshDebugShortcuts), 1123 }, 1124 #endif 1125 { 1126 "enable-contacts", 1127 IDS_FLAGS_ENABLE_CONTACTS_NAME, 1128 IDS_FLAGS_ENABLE_CONTACTS_DESCRIPTION, 1129 kOsCrOS, 1130 SINGLE_VALUE_TYPE(switches::kEnableContacts) 1131 }, 1132 #if defined(USE_ASH) 1133 { "ash-enable-advanced-gestures", 1134 IDS_FLAGS_ENABLE_ADVANCED_GESTURES_NAME, 1135 IDS_FLAGS_ENABLE_ADVANCED_GESTURES_DESCRIPTION, 1136 kOsCrOS, 1137 SINGLE_VALUE_TYPE(ash::switches::kAshEnableAdvancedGestures), 1138 }, 1139 { "ash-disable-tab-scrubbing", 1140 IDS_FLAGS_DISABLE_TAB_SCRUBBING_NAME, 1141 IDS_FLAGS_DISABLE_TAB_SCRUBBING_DESCRIPTION, 1142 kOsCrOS, 1143 SINGLE_VALUE_TYPE(switches::kAshDisableTabScrubbing), 1144 }, 1145 { "ash-disable-drag-and-drop-applist-to-launcher", 1146 IDS_FLAGS_DND_APPLIST_TO_LAUNCHER_NAME, 1147 IDS_FLAGS_DND_APPLIST_TO_LAUNCHER_DESCRIPTION, 1148 kOsCrOS, 1149 SINGLE_VALUE_TYPE(ash::switches::kAshDisableDragAndDropAppListToLauncher), 1150 }, 1151 { "ash-immersive-fullscreen-2", 1152 IDS_FLAGS_ASH_IMMERSIVE_FULLSCREEN_NAME, 1153 IDS_FLAGS_ASH_IMMERSIVE_FULLSCREEN_DESCRIPTION, 1154 kOsCrOS, 1155 ENABLE_DISABLE_VALUE_TYPE(ash::switches::kAshEnableImmersiveFullscreen, 1156 ash::switches::kAshDisableImmersiveFullscreen), 1157 }, 1158 #if defined(OS_LINUX) 1159 { "ash-enable-memory-monitor", 1160 IDS_FLAGS_ENABLE_MEMORY_MONITOR_NAME, 1161 IDS_FLAGS_ENABLE_MEMORY_MONITOR_DESCRIPTION, 1162 kOsCrOS, 1163 SINGLE_VALUE_TYPE(ash::switches::kAshEnableMemoryMonitor), 1164 }, 1165 #endif 1166 #endif 1167 #if defined(OS_CHROMEOS) 1168 { "use-new-network-configuration-handlers", 1169 IDS_FLAGS_CHROMEOS_USE_NEW_NETWORK_CONFIGURATION_HANDLERS_NAME, 1170 IDS_FLAGS_CHROMEOS_USE_NEW_NETWORK_CONFIGURATION_HANDLERS_DESCRIPTION, 1171 kOsCrOS, 1172 SINGLE_VALUE_TYPE(chromeos::switches::kUseNewNetworkConfigurationHandlers), 1173 }, 1174 { 1175 "ash-audio-device-menu", 1176 IDS_FLAGS_ASH_AUDIO_DEVICE_MENU_NAME, 1177 IDS_FLAGS_ASH_AUDIO_DEVICE_MENU_DESCRIPTION, 1178 kOsCrOS, 1179 ENABLE_DISABLE_VALUE_TYPE(ash::switches::kAshEnableAudioDeviceMenu, 1180 ash::switches::kAshDisableAudioDeviceMenu) 1181 }, 1182 { 1183 "enable-carrier-switching", 1184 IDS_FLAGS_ENABLE_CARRIER_SWITCHING, 1185 IDS_FLAGS_ENABLE_CARRIER_SWITCHING_DESCRIPTION, 1186 kOsCrOS, 1187 SINGLE_VALUE_TYPE(chromeos::switches::kEnableCarrierSwitching) 1188 }, 1189 { 1190 "enable-request-tablet-site", 1191 IDS_FLAGS_ENABLE_REQUEST_TABLET_SITE_NAME, 1192 IDS_FLAGS_ENABLE_REQUEST_TABLET_SITE_DESCRIPTION, 1193 kOsCrOS, 1194 SINGLE_VALUE_TYPE(chromeos::switches::kEnableRequestTabletSite) 1195 }, 1196 #endif 1197 { 1198 "debug-packed-apps", 1199 IDS_FLAGS_DEBUG_PACKED_APP_NAME, 1200 IDS_FLAGS_DEBUG_PACKED_APP_DESCRIPTION, 1201 kOsDesktop, 1202 SINGLE_VALUE_TYPE(switches::kDebugPackedApps) 1203 }, 1204 { 1205 "enable-password-generation", 1206 IDS_FLAGS_ENABLE_PASSWORD_GENERATION_NAME, 1207 IDS_FLAGS_ENABLE_PASSWORD_GENERATION_DESCRIPTION, 1208 kOsDesktop, 1209 SINGLE_VALUE_TYPE(switches::kEnablePasswordGeneration) 1210 }, 1211 { 1212 "password-autofill-public-suffix-domain-matching", 1213 IDS_FLAGS_PASSWORD_AUTOFILL_PUBLIC_SUFFIX_DOMAIN_MATCHING_NAME, 1214 IDS_FLAGS_PASSWORD_AUTOFILL_PUBLIC_SUFFIX_DOMAIN_MATCHING_DESCRIPTION, 1215 kOsAndroid, 1216 ENABLE_DISABLE_VALUE_TYPE( 1217 switches::kEnablePasswordAutofillPublicSuffixDomainMatching, 1218 switches::kDisablePasswordAutofillPublicSuffixDomainMatching) 1219 }, 1220 { 1221 "enable-deferred-image-decoding", 1222 IDS_FLAGS_ENABLE_DEFERRED_IMAGE_DECODING_NAME, 1223 IDS_FLAGS_ENABLE_DEFERRED_IMAGE_DECODING_DESCRIPTION, 1224 kOsMac | kOsLinux | kOsCrOS, 1225 SINGLE_VALUE_TYPE(switches::kEnableDeferredImageDecoding) 1226 }, 1227 { 1228 "performance-monitor-gathering", 1229 IDS_FLAGS_PERFORMANCE_MONITOR_GATHERING_NAME, 1230 IDS_FLAGS_PERFORMANCE_MONITOR_GATHERING_DESCRIPTION, 1231 kOsAll, 1232 SINGLE_VALUE_TYPE(switches::kPerformanceMonitorGathering) 1233 }, 1234 { 1235 "enable-experimental-form-filling", 1236 IDS_FLAGS_ENABLE_EXPERIMENTAL_FORM_FILLING_NAME, 1237 IDS_FLAGS_ENABLE_EXPERIMENTAL_FORM_FILLING_DESCRIPTION, 1238 kOsWin | kOsCrOS, 1239 SINGLE_VALUE_TYPE(autofill::switches::kEnableExperimentalFormFilling) 1240 }, 1241 { 1242 "wallet-service-use-prod", 1243 IDS_FLAGS_ENABLE_WALLET_PRODUCTION_SERVICE_NAME, 1244 IDS_FLAGS_ENABLE_WALLET_PRODUCTION_SERVICE_DESCRIPTION, 1245 kOsCrOS | kOsWin, 1246 SINGLE_VALUE_TYPE(autofill::switches::kWalletServiceUseProd) 1247 }, 1248 { 1249 "enable-interactive-autocomplete", 1250 IDS_FLAGS_ENABLE_INTERACTIVE_AUTOCOMPLETE_NAME, 1251 IDS_FLAGS_ENABLE_INTERACTIVE_AUTOCOMPLETE_DESCRIPTION, 1252 kOsWin | kOsCrOS | kOsMac, 1253 ENABLE_DISABLE_VALUE_TYPE( 1254 autofill::switches::kEnableInteractiveAutocomplete, 1255 autofill::switches::kDisableInteractiveAutocomplete) 1256 }, 1257 #if defined(USE_AURA) 1258 { 1259 "overscroll-history-navigation", 1260 IDS_FLAGS_OVERSCROLL_HISTORY_NAVIGATION_NAME, 1261 IDS_FLAGS_OVERSCROLL_HISTORY_NAVIGATION_DESCRIPTION, 1262 kOsAll, 1263 ENABLE_DISABLE_VALUE_TYPE_AND_VALUE( 1264 switches::kOverscrollHistoryNavigation, "1", 1265 switches::kOverscrollHistoryNavigation, "0") 1266 }, 1267 #endif 1268 { 1269 "scroll-end-effect", 1270 IDS_FLAGS_SCROLL_END_EFFECT_NAME, 1271 IDS_FLAGS_SCROLL_END_EFFECT_DESCRIPTION, 1272 kOsCrOS, 1273 ENABLE_DISABLE_VALUE_TYPE_AND_VALUE( 1274 switches::kScrollEndEffect, "1", 1275 switches::kScrollEndEffect, "0") 1276 }, 1277 { 1278 "enable-touch-side-bezels", 1279 IDS_FLAGS_ENABLE_TOUCH_SIDE_BEZELS_NAME, 1280 IDS_FLAGS_ENABLE_TOUCH_SIDE_BEZELS_DESCRIPTION, 1281 kOsCrOS, 1282 ENABLE_DISABLE_VALUE_TYPE_AND_VALUE( 1283 switches::kTouchSideBezels, "1", 1284 switches::kTouchSideBezels, "0") 1285 }, 1286 { 1287 "enable-touch-drag-drop", 1288 IDS_FLAGS_ENABLE_TOUCH_DRAG_DROP_NAME, 1289 IDS_FLAGS_ENABLE_TOUCH_DRAG_DROP_DESCRIPTION, 1290 kOsWin | kOsCrOS, 1291 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableTouchDragDrop, 1292 switches::kDisableTouchDragDrop) 1293 }, 1294 { 1295 "enable-touch-editing", 1296 IDS_FLAGS_ENABLE_TOUCH_EDITING_NAME, 1297 IDS_FLAGS_ENABLE_TOUCH_EDITING_DESCRIPTION, 1298 kOsCrOS, 1299 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableTouchEditing, 1300 switches::kDisableTouchEditing) 1301 }, 1302 { 1303 "enable-rich-notifications", 1304 IDS_FLAGS_ENABLE_RICH_NOTIFICATIONS_NAME, 1305 IDS_FLAGS_ENABLE_RICH_NOTIFICATIONS_DESCRIPTION, 1306 kOsWin | kOsMac, 1307 ENABLE_DISABLE_VALUE_TYPE( 1308 message_center::switches::kEnableRichNotifications, 1309 message_center::switches::kDisableRichNotifications) 1310 }, 1311 { 1312 "enable-sync-synced-notifications", 1313 IDS_FLAGS_ENABLE_SYNCED_NOTIFICATIONS_NAME, 1314 IDS_FLAGS_ENABLE_SYNCED_NOTIFICATIONS_DESCRIPTION, 1315 kOsDesktop, 1316 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableSyncSyncedNotifications, 1317 switches::kDisableSyncSyncedNotifications) 1318 }, 1319 { 1320 "disable-full-history-sync", 1321 IDS_FLAGS_FULL_HISTORY_SYNC_NAME, 1322 IDS_FLAGS_FULL_HISTORY_SYNC_DESCRIPTION, 1323 kOsAll, 1324 SINGLE_VALUE_TYPE(switches::kHistoryDisableFullHistorySync) 1325 }, 1326 { 1327 "enable-usermedia-screen-capture", 1328 IDS_FLAGS_ENABLE_SCREEN_CAPTURE_NAME, 1329 IDS_FLAGS_ENABLE_SCREEN_CAPTURE_DESCRIPTION, 1330 kOsDesktop, 1331 SINGLE_VALUE_TYPE(switches::kEnableUserMediaScreenCapturing) 1332 }, 1333 { 1334 "enable-apps-devtool-app", 1335 IDS_FLAGS_ENABLE_APPS_DEVTOOL_APP_NAME, 1336 IDS_FLAGS_ENABLE_APPS_DEVTOOL_APP_DESCRIPTION, 1337 kOsDesktop, 1338 SINGLE_VALUE_TYPE(switches::kAppsDevtool) 1339 }, 1340 { 1341 "impl-side-painting", 1342 IDS_FLAGS_IMPL_SIDE_PAINTING_NAME, 1343 IDS_FLAGS_IMPL_SIDE_PAINTING_DESCRIPTION, 1344 kOsAndroid | kOsLinux | kOsCrOS, 1345 MULTI_VALUE_TYPE(kImplSidePaintingChoices) 1346 }, 1347 { 1348 "delegated-renderer", 1349 IDS_FLAGS_DELEGATED_RENDERER_NAME, 1350 IDS_FLAGS_DELEGATED_RENDERER_DESCRIPTION, 1351 #ifdef USE_AURA 1352 kOsWin | kOsLinux | 1353 #endif 1354 kOsAndroid | kOsCrOS, 1355 MULTI_VALUE_TYPE(kDelegatedRendererChoices) 1356 }, 1357 { 1358 "enable-websocket-experimental-implementation", 1359 IDS_FLAGS_ENABLE_EXPERIMENTAL_WEBSOCKET_NAME, 1360 IDS_FLAGS_ENABLE_EXPERIMENTAL_WEBSOCKET_DESCRIPTION, 1361 kOsAll, 1362 SINGLE_VALUE_TYPE(switches::kEnableExperimentalWebSocket) 1363 }, 1364 { 1365 "max-tiles-for-interest-area", 1366 IDS_FLAGS_MAX_TILES_FOR_INTEREST_AREA_NAME, 1367 IDS_FLAGS_MAX_TILES_FOR_INTEREST_AREA_DESCRIPTION, 1368 kOsAndroid | kOsLinux | kOsCrOS, 1369 MULTI_VALUE_TYPE(kMaxTilesForInterestAreaChoices) 1370 }, 1371 { 1372 "enable-offline-mode", 1373 IDS_FLAGS_ENABLE_OFFLINE_MODE_NAME, 1374 IDS_FLAGS_ENABLE_OFFLINE_MODE_DESCRIPTION, 1375 kOsAll, 1376 SINGLE_VALUE_TYPE(switches::kEnableOfflineCacheAccess) 1377 }, 1378 { 1379 "default-tile-width", 1380 IDS_FLAGS_DEFAULT_TILE_WIDTH_NAME, 1381 IDS_FLAGS_DEFAULT_TILE_WIDTH_DESCRIPTION, 1382 kOsAll, 1383 MULTI_VALUE_TYPE(kDefaultTileWidthChoices) 1384 }, 1385 { 1386 "default-tile-height", 1387 IDS_FLAGS_DEFAULT_TILE_HEIGHT_NAME, 1388 IDS_FLAGS_DEFAULT_TILE_HEIGHT_DESCRIPTION, 1389 kOsAll, 1390 MULTI_VALUE_TYPE(kDefaultTileHeightChoices) 1391 }, 1392 // TODO(sky): ifdef needed until focus sorted out in DesktopNativeWidgetAura. 1393 #if !defined(USE_AURA) 1394 { 1395 "track-active-visit-time", 1396 IDS_FLAGS_TRACK_ACTIVE_VISIT_TIME_NAME, 1397 IDS_FLAGS_TRACK_ACTIVE_VISIT_TIME_DESCRIPTION, 1398 kOsWin, 1399 SINGLE_VALUE_TYPE(switches::kTrackActiveVisitTime) 1400 }, 1401 #endif 1402 #if defined(OS_ANDROID) 1403 { 1404 "disable-gesture-requirement-for-media-playback", 1405 IDS_FLAGS_DISABLE_GESTURE_REQUIREMENT_FOR_MEDIA_PLAYBACK_NAME, 1406 IDS_FLAGS_DISABLE_GESTURE_REQUIREMENT_FOR_MEDIA_PLAYBACK_DESCRIPTION, 1407 kOsAndroid, 1408 SINGLE_VALUE_TYPE(switches::kDisableGestureRequirementForMediaPlayback) 1409 }, 1410 #endif 1411 #if defined(ENABLE_GOOGLE_NOW) 1412 { 1413 "enable-google-now", 1414 IDS_FLAGS_ENABLE_GOOGLE_NOW_INTEGRATION_NAME, 1415 IDS_FLAGS_ENABLE_GOOGLE_NOW_INTEGRATION_DESCRIPTION, 1416 kOsWin | kOsCrOS | kOsMac, 1417 SINGLE_VALUE_TYPE(switches::kEnableGoogleNowIntegration) 1418 }, 1419 #endif 1420 #if defined(OS_CHROMEOS) 1421 { 1422 "enable-virtual-keyboard", 1423 IDS_FLAGS_ENABLE_VIRTUAL_KEYBOARD_NAME, 1424 IDS_FLAGS_ENABLE_VIRTUAL_KEYBOARD_DESCRIPTION, 1425 kOsCrOS, 1426 SINGLE_VALUE_TYPE(keyboard::switches::kEnableVirtualKeyboard) 1427 }, 1428 #endif 1429 { 1430 "enable-simple-cache-backend", 1431 IDS_FLAGS_ENABLE_SIMPLE_CACHE_BACKEND_NAME, 1432 IDS_FLAGS_ENABLE_SIMPLE_CACHE_BACKEND_DESCRIPTION, 1433 kOsAll, 1434 MULTI_VALUE_TYPE(kSimpleCacheBackendChoices) 1435 }, 1436 { 1437 "enable-tcp-fast-open", 1438 IDS_FLAGS_ENABLE_TCP_FAST_OPEN_NAME, 1439 IDS_FLAGS_ENABLE_TCP_FAST_OPEN_DESCRIPTION, 1440 kOsLinux | kOsCrOS | kOsAndroid, 1441 SINGLE_VALUE_TYPE(switches::kEnableTcpFastOpen) 1442 }, 1443 { 1444 "apps-use-native-frame", 1445 IDS_FLAGS_ENABLE_NATIVE_FRAMES_FOR_APPS_NAME, 1446 IDS_FLAGS_ENABLE_NATIVE_FRAMES_FOR_APPS_DESCRIPTION, 1447 kOsMac | kOsWin, 1448 SINGLE_VALUE_TYPE(switches::kAppsUseNativeFrame) 1449 }, 1450 { 1451 "enable-syncfs-directory-operation", 1452 IDS_FLAGS_ENABLE_SYNC_DIRECTORY_OPERATION_NAME, 1453 IDS_FLAGS_ENABLE_SYNC_DIRECTORY_OPERATION_DESCRIPTION, 1454 kOsAll, 1455 SINGLE_VALUE_TYPE(switches::kSyncfsEnableDirectoryOperation), 1456 }, 1457 { 1458 "enable-reset-profile-settings", 1459 IDS_FLAGS_ENABLE_RESET_PROFILE_SETTINGS_NAME, 1460 IDS_FLAGS_ENABLE_RESET_PROFILE_SETTINGS_DESCRIPTION, 1461 kOsAll, 1462 SINGLE_VALUE_TYPE(switches::kEnableResetProfileSettings) 1463 }, 1464 { 1465 "enable-device-discovery", 1466 IDS_FLAGS_ENABLE_DEVICE_DISCOVERY_NAME, 1467 IDS_FLAGS_ENABLE_DEVICE_DISCOVERY_DESCRIPTION, 1468 kOsDesktop, 1469 SINGLE_VALUE_TYPE(switches::kEnableDeviceDiscovery) 1470 }, 1471 #if defined(OS_MACOSX) 1472 { 1473 "enable-app-list-shim", 1474 IDS_FLAGS_ENABLE_APP_LIST_SHIM_NAME, 1475 IDS_FLAGS_ENABLE_APP_LIST_SHIM_DESCRIPTION, 1476 kOsMac, 1477 SINGLE_VALUE_TYPE(switches::kEnableAppListShim) 1478 }, 1479 { 1480 "enable-app-shims", 1481 IDS_FLAGS_ENABLE_APP_SHIMS_NAME, 1482 IDS_FLAGS_ENABLE_APP_SHIMS_DESCRIPTION, 1483 kOsMac, 1484 SINGLE_VALUE_TYPE(switches::kEnableAppShims) 1485 }, 1486 { 1487 "enable-simplified-fullscreen", 1488 IDS_FLAGS_ENABLE_SIMPLIFIED_FULLSCREEN_NAME, 1489 IDS_FLAGS_ENABLE_SIMPLIFIED_FULLSCREEN_DESCRIPTION, 1490 kOsMac, 1491 SINGLE_VALUE_TYPE(switches::kEnableSimplifiedFullscreen) 1492 }, 1493 #endif 1494 #if defined(OS_CHROMEOS) || defined(OS_WIN) 1495 { 1496 "omnibox-auto-completion-for-ime", 1497 IDS_FLAGS_ENABLE_OMNIBOX_AUTO_COMPLETION_FOR_IME_NAME, 1498 IDS_FLAGS_ENABLE_OMNIBOX_AUTO_COMPLETION_FOR_IME_DESCRIPTION, 1499 kOsCrOS | kOsWin, 1500 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableOmniboxAutoCompletionForIme, 1501 switches::kDisableOmniboxAutoCompletionForIme) 1502 }, 1503 #endif 1504 #if defined(USE_AURA) 1505 { 1506 "tab-capture-upscale-quality", 1507 IDS_FLAGS_TAB_CAPTURE_UPSCALE_QUALITY_NAME, 1508 IDS_FLAGS_TAB_CAPTURE_UPSCALE_QUALITY_DESCRIPTION, 1509 kOsAll, 1510 MULTI_VALUE_TYPE(kTabCaptureUpscaleQualityChoices) 1511 }, 1512 { 1513 "tab-capture-downscale-quality", 1514 IDS_FLAGS_TAB_CAPTURE_DOWNSCALE_QUALITY_NAME, 1515 IDS_FLAGS_TAB_CAPTURE_DOWNSCALE_QUALITY_DESCRIPTION, 1516 kOsAll, 1517 MULTI_VALUE_TYPE(kTabCaptureDownscaleQualityChoices) 1518 }, 1519 #endif 1520 { 1521 "enable-spelling-service-feedback", 1522 IDS_FLAGS_ENABLE_SPELLING_SERVICE_FEEDBACK_NAME, 1523 IDS_FLAGS_ENABLE_SPELLING_SERVICE_FEEDBACK_DESCRIPTION, 1524 kOsAll, 1525 SINGLE_VALUE_TYPE(switches::kEnableSpellingServiceFeedback) 1526 }, 1527 { 1528 "enable-webgl-draft-extensions", 1529 IDS_FLAGS_ENABLE_WEBGL_DRAFT_EXTENSIONS_NAME, 1530 IDS_FLAGS_ENABLE_WEBGL_DRAFT_EXTENSIONS_DESCRIPTION, 1531 kOsAll, 1532 SINGLE_VALUE_TYPE(switches::kEnableWebGLDraftExtensions) 1533 }, 1534 { 1535 "enable-html-imports", 1536 IDS_FLAGS_ENABLE_HTML_IMPORTS_NAME, 1537 IDS_FLAGS_ENABLE_HTML_IMPORTS_DESCRIPTION, 1538 kOsAll, 1539 SINGLE_VALUE_TYPE(switches::kEnableHTMLImports) 1540 }, 1541 { 1542 "high-dpi-support", 1543 IDS_FLAGS_HIDPI_NAME, 1544 IDS_FLAGS_HIDPI_DESCRIPTION, 1545 kOsWin, 1546 ENABLE_DISABLE_VALUE_TYPE_AND_VALUE(switches::kHighDPISupport,"1", 1547 switches::kHighDPISupport,"0") 1548 }, 1549 #if defined(OS_CHROMEOS) 1550 { 1551 "enable-quickoffice-viewing", 1552 IDS_FLAGS_ENABLE_QUICKOFFICE_DESKTOP_VIEWING_NAME, 1553 IDS_FLAGS_ENABLE_QUICKOFFICE_DESKTOP_VIEWING_DESCRIPTION, 1554 kOsCrOS, 1555 SINGLE_VALUE_TYPE(switches::kEnableQuickofficeViewing), 1556 }, 1557 { 1558 "enable-sticky-keys", 1559 IDS_FLAGS_ENABLE_STICKY_KEYS_NAME, 1560 IDS_FLAGS_ENABLE_STICKY_KEYS_DESCRIPTION, 1561 kOsCrOS, 1562 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableStickyKeys, 1563 switches::kDisableStickyKeys) 1564 }, 1565 #endif 1566 { 1567 "enable-translate-settings", 1568 IDS_FLAGS_ENABLE_TRANSLATE_SETTINGS_NAME, 1569 IDS_FLAGS_ENABLE_TRANSLATE_SETTINGS_DESCRIPTION, 1570 kOsAll, 1571 SINGLE_VALUE_TYPE(switches::kEnableTranslateSettings) 1572 }, 1573 { 1574 "enable-web-midi", 1575 IDS_FLAGS_ENABLE_WEB_MIDI_NAME, 1576 IDS_FLAGS_ENABLE_WEB_MIDI_DESCRIPTION, 1577 kOsMac, 1578 SINGLE_VALUE_TYPE(switches::kEnableWebMIDI) 1579 }, 1580 { 1581 "enable-new-profile-management", 1582 IDS_FLAGS_ENABLE_NEW_PROFILE_MANAGEMENT_NAME, 1583 IDS_FLAGS_ENABLE_NEW_PROFILE_MANAGEMENT_DESCRIPTION, 1584 kOsWin, 1585 SINGLE_VALUE_TYPE(switches::kNewProfileManagement) 1586 }, 1587 { 1588 "enable-gaia-profile-info", 1589 IDS_FLAGS_ENABLE_GAIA_PROFILE_INFO_NAME, 1590 IDS_FLAGS_ENABLE_GAIA_PROFILE_INFO_DESCRIPTION, 1591 kOsMac | kOsWin | kOsLinux, 1592 SINGLE_VALUE_TYPE(switches::kGaiaProfileInfo) 1593 }, 1594 #if defined(OS_WIN) 1595 { 1596 "disable-app-launcher", 1597 IDS_FLAGS_DISABLE_APP_LIST_NAME, 1598 IDS_FLAGS_DISABLE_APP_LIST_DESCRIPTION, 1599 kOsAll, 1600 SINGLE_VALUE_TYPE(switches::kDisableAppList) 1601 }, 1602 #endif 1603 { 1604 "disable-compositor-touch-hit-testing", 1605 IDS_FLAGS_DISABLE_COMPOSITOR_TOUCH_HIT_TESTING_NAME, 1606 IDS_FLAGS_DISABLE_COMPOSITOR_TOUCH_HIT_TESTING_DESCRIPTION, 1607 kOsAll, 1608 SINGLE_VALUE_TYPE(cc::switches::kDisableCompositorTouchHitTesting), 1609 }, 1610 }; 1611 1612 const Experiment* experiments = kExperiments; 1613 size_t num_experiments = arraysize(kExperiments); 1614 1615 // Stores and encapsulates the little state that about:flags has. 1616 class FlagsState { 1617 public: 1618 FlagsState() : needs_restart_(false) {} 1619 void ConvertFlagsToSwitches(FlagsStorage* flags_storage, 1620 CommandLine* command_line); 1621 bool IsRestartNeededToCommitChanges(); 1622 void SetExperimentEnabled( 1623 FlagsStorage* flags_storage, 1624 const std::string& internal_name, 1625 bool enable); 1626 void RemoveFlagsSwitches( 1627 std::map<std::string, CommandLine::StringType>* switch_list); 1628 void ResetAllFlags(FlagsStorage* flags_storage); 1629 void reset(); 1630 1631 // Returns the singleton instance of this class 1632 static FlagsState* GetInstance() { 1633 return Singleton<FlagsState>::get(); 1634 } 1635 1636 private: 1637 bool needs_restart_; 1638 std::map<std::string, std::string> flags_switches_; 1639 1640 DISALLOW_COPY_AND_ASSIGN(FlagsState); 1641 }; 1642 1643 // Adds the internal names for the specified experiment to |names|. 1644 void AddInternalName(const Experiment& e, std::set<std::string>* names) { 1645 if (e.type == Experiment::SINGLE_VALUE) { 1646 names->insert(e.internal_name); 1647 } else { 1648 DCHECK(e.type == Experiment::MULTI_VALUE || 1649 e.type == Experiment::ENABLE_DISABLE_VALUE); 1650 for (int i = 0; i < e.num_choices; ++i) 1651 names->insert(e.NameForChoice(i)); 1652 } 1653 } 1654 1655 // Confirms that an experiment is valid, used in a DCHECK in 1656 // SanitizeList below. 1657 bool ValidateExperiment(const Experiment& e) { 1658 switch (e.type) { 1659 case Experiment::SINGLE_VALUE: 1660 DCHECK_EQ(0, e.num_choices); 1661 DCHECK(!e.choices); 1662 break; 1663 case Experiment::MULTI_VALUE: 1664 DCHECK_GT(e.num_choices, 0); 1665 DCHECK(e.choices); 1666 DCHECK(e.choices[0].command_line_switch); 1667 DCHECK_EQ('\0', e.choices[0].command_line_switch[0]); 1668 break; 1669 case Experiment::ENABLE_DISABLE_VALUE: 1670 DCHECK_EQ(3, e.num_choices); 1671 DCHECK(!e.choices); 1672 DCHECK(e.command_line_switch); 1673 DCHECK(e.command_line_value); 1674 DCHECK(e.disable_command_line_switch); 1675 DCHECK(e.disable_command_line_value); 1676 break; 1677 default: 1678 NOTREACHED(); 1679 } 1680 return true; 1681 } 1682 1683 // Removes all experiments from prefs::kEnabledLabsExperiments that are 1684 // unknown, to prevent this list to become very long as experiments are added 1685 // and removed. 1686 void SanitizeList(FlagsStorage* flags_storage) { 1687 std::set<std::string> known_experiments; 1688 for (size_t i = 0; i < num_experiments; ++i) { 1689 DCHECK(ValidateExperiment(experiments[i])); 1690 AddInternalName(experiments[i], &known_experiments); 1691 } 1692 1693 std::set<std::string> enabled_experiments = flags_storage->GetFlags(); 1694 1695 std::set<std::string> new_enabled_experiments; 1696 std::set_intersection( 1697 known_experiments.begin(), known_experiments.end(), 1698 enabled_experiments.begin(), enabled_experiments.end(), 1699 std::inserter(new_enabled_experiments, new_enabled_experiments.begin())); 1700 1701 if (new_enabled_experiments != enabled_experiments) 1702 flags_storage->SetFlags(new_enabled_experiments); 1703 } 1704 1705 void GetSanitizedEnabledFlags( 1706 FlagsStorage* flags_storage, std::set<std::string>* result) { 1707 SanitizeList(flags_storage); 1708 *result = flags_storage->GetFlags(); 1709 } 1710 1711 // Variant of GetSanitizedEnabledFlags that also removes any flags that aren't 1712 // enabled on the current platform. 1713 void GetSanitizedEnabledFlagsForCurrentPlatform( 1714 FlagsStorage* flags_storage, std::set<std::string>* result) { 1715 GetSanitizedEnabledFlags(flags_storage, result); 1716 1717 // Filter out any experiments that aren't enabled on the current platform. We 1718 // don't remove these from prefs else syncing to a platform with a different 1719 // set of experiments would be lossy. 1720 std::set<std::string> platform_experiments; 1721 int current_platform = GetCurrentPlatform(); 1722 for (size_t i = 0; i < num_experiments; ++i) { 1723 if (experiments[i].supported_platforms & current_platform) 1724 AddInternalName(experiments[i], &platform_experiments); 1725 #if defined(OS_CHROMEOS) 1726 if (experiments[i].supported_platforms & kOsCrOSOwnerOnly) 1727 AddInternalName(experiments[i], &platform_experiments); 1728 #endif 1729 } 1730 1731 std::set<std::string> new_enabled_experiments; 1732 std::set_intersection( 1733 platform_experiments.begin(), platform_experiments.end(), 1734 result->begin(), result->end(), 1735 std::inserter(new_enabled_experiments, new_enabled_experiments.begin())); 1736 1737 result->swap(new_enabled_experiments); 1738 } 1739 1740 // Returns the Value representing the choice data in the specified experiment. 1741 Value* CreateChoiceData(const Experiment& experiment, 1742 const std::set<std::string>& enabled_experiments) { 1743 DCHECK(experiment.type == Experiment::MULTI_VALUE || 1744 experiment.type == Experiment::ENABLE_DISABLE_VALUE); 1745 ListValue* result = new ListValue; 1746 for (int i = 0; i < experiment.num_choices; ++i) { 1747 DictionaryValue* value = new DictionaryValue; 1748 const std::string name = experiment.NameForChoice(i); 1749 value->SetString("internal_name", name); 1750 value->SetString("description", experiment.DescriptionForChoice(i)); 1751 value->SetBoolean("selected", enabled_experiments.count(name) > 0); 1752 result->Append(value); 1753 } 1754 return result; 1755 } 1756 1757 } // namespace 1758 1759 std::string Experiment::NameForChoice(int index) const { 1760 DCHECK(type == Experiment::MULTI_VALUE || 1761 type == Experiment::ENABLE_DISABLE_VALUE); 1762 DCHECK_LT(index, num_choices); 1763 return std::string(internal_name) + testing::kMultiSeparator + 1764 base::IntToString(index); 1765 } 1766 1767 string16 Experiment::DescriptionForChoice(int index) const { 1768 DCHECK(type == Experiment::MULTI_VALUE || 1769 type == Experiment::ENABLE_DISABLE_VALUE); 1770 DCHECK_LT(index, num_choices); 1771 int description_id; 1772 if (type == Experiment::ENABLE_DISABLE_VALUE) { 1773 const int kEnableDisableDescriptionIds[] = { 1774 IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, 1775 IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 1776 IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 1777 }; 1778 description_id = kEnableDisableDescriptionIds[index]; 1779 } else { 1780 description_id = choices[index].description_id; 1781 } 1782 return l10n_util::GetStringUTF16(description_id); 1783 } 1784 1785 void ConvertFlagsToSwitches(FlagsStorage* flags_storage, 1786 CommandLine* command_line) { 1787 FlagsState::GetInstance()->ConvertFlagsToSwitches(flags_storage, 1788 command_line); 1789 } 1790 1791 bool AreSwitchesIdenticalToCurrentCommandLine( 1792 const CommandLine& new_cmdline, const CommandLine& active_cmdline) { 1793 std::set<CommandLine::StringType> new_flags = 1794 ExtractFlagsFromCommandLine(new_cmdline); 1795 std::set<CommandLine::StringType> active_flags = 1796 ExtractFlagsFromCommandLine(active_cmdline); 1797 1798 // Needed because std::equal doesn't check if the 2nd set is empty. 1799 if (new_flags.size() != active_flags.size()) 1800 return false; 1801 1802 return std::equal(new_flags.begin(), new_flags.end(), active_flags.begin()); 1803 } 1804 1805 void GetFlagsExperimentsData(FlagsStorage* flags_storage, 1806 FlagAccess access, 1807 base::ListValue* supported_experiments, 1808 base::ListValue* unsupported_experiments) { 1809 std::set<std::string> enabled_experiments; 1810 GetSanitizedEnabledFlags(flags_storage, &enabled_experiments); 1811 1812 int current_platform = GetCurrentPlatform(); 1813 1814 for (size_t i = 0; i < num_experiments; ++i) { 1815 const Experiment& experiment = experiments[i]; 1816 1817 DictionaryValue* data = new DictionaryValue(); 1818 data->SetString("internal_name", experiment.internal_name); 1819 data->SetString("name", 1820 l10n_util::GetStringUTF16(experiment.visible_name_id)); 1821 data->SetString("description", 1822 l10n_util::GetStringUTF16( 1823 experiment.visible_description_id)); 1824 1825 ListValue* supported_platforms = new ListValue(); 1826 AddOsStrings(experiment.supported_platforms, supported_platforms); 1827 data->Set("supported_platforms", supported_platforms); 1828 1829 switch (experiment.type) { 1830 case Experiment::SINGLE_VALUE: 1831 data->SetBoolean( 1832 "enabled", 1833 enabled_experiments.count(experiment.internal_name) > 0); 1834 break; 1835 case Experiment::MULTI_VALUE: 1836 case Experiment::ENABLE_DISABLE_VALUE: 1837 data->Set("choices", CreateChoiceData(experiment, enabled_experiments)); 1838 break; 1839 default: 1840 NOTREACHED(); 1841 } 1842 1843 bool supported = (experiment.supported_platforms & current_platform) != 0; 1844 #if defined(OS_CHROMEOS) 1845 if (access == kOwnerAccessToFlags && 1846 (experiment.supported_platforms & kOsCrOSOwnerOnly) != 0) { 1847 supported = true; 1848 } 1849 #endif 1850 if (supported) 1851 supported_experiments->Append(data); 1852 else 1853 unsupported_experiments->Append(data); 1854 } 1855 } 1856 1857 bool IsRestartNeededToCommitChanges() { 1858 return FlagsState::GetInstance()->IsRestartNeededToCommitChanges(); 1859 } 1860 1861 void SetExperimentEnabled(FlagsStorage* flags_storage, 1862 const std::string& internal_name, 1863 bool enable) { 1864 FlagsState::GetInstance()->SetExperimentEnabled(flags_storage, 1865 internal_name, enable); 1866 } 1867 1868 void RemoveFlagsSwitches( 1869 std::map<std::string, CommandLine::StringType>* switch_list) { 1870 FlagsState::GetInstance()->RemoveFlagsSwitches(switch_list); 1871 } 1872 1873 void ResetAllFlags(FlagsStorage* flags_storage) { 1874 FlagsState::GetInstance()->ResetAllFlags(flags_storage); 1875 } 1876 1877 int GetCurrentPlatform() { 1878 #if defined(OS_MACOSX) 1879 return kOsMac; 1880 #elif defined(OS_WIN) 1881 return kOsWin; 1882 #elif defined(OS_CHROMEOS) // Needs to be before the OS_LINUX check. 1883 return kOsCrOS; 1884 #elif defined(OS_LINUX) || defined(OS_OPENBSD) 1885 return kOsLinux; 1886 #elif defined(OS_ANDROID) 1887 return kOsAndroid; 1888 #else 1889 #error Unknown platform 1890 #endif 1891 } 1892 1893 void RecordUMAStatistics(FlagsStorage* flags_storage) { 1894 std::set<std::string> flags = flags_storage->GetFlags(); 1895 for (std::set<std::string>::iterator it = flags.begin(); it != flags.end(); 1896 ++it) { 1897 std::string action("AboutFlags_"); 1898 action += *it; 1899 content::RecordComputedAction(action); 1900 } 1901 // Since flag metrics are recorded every startup, add a tick so that the 1902 // stats can be made meaningful. 1903 if (flags.size()) 1904 content::RecordAction(UserMetricsAction("AboutFlags_StartupTick")); 1905 content::RecordAction(UserMetricsAction("StartupTick")); 1906 } 1907 1908 ////////////////////////////////////////////////////////////////////////////// 1909 // FlagsState implementation. 1910 1911 namespace { 1912 1913 typedef std::map<std::string, std::pair<std::string, std::string> > 1914 NameToSwitchAndValueMap; 1915 1916 void SetFlagToSwitchMapping(const std::string& key, 1917 const std::string& switch_name, 1918 const std::string& switch_value, 1919 NameToSwitchAndValueMap* name_to_switch_map) { 1920 DCHECK(name_to_switch_map->end() == name_to_switch_map->find(key)); 1921 (*name_to_switch_map)[key] = std::make_pair(switch_name, switch_value); 1922 } 1923 1924 void FlagsState::ConvertFlagsToSwitches( 1925 FlagsStorage* flags_storage, CommandLine* command_line) { 1926 if (command_line->HasSwitch(switches::kNoExperiments)) 1927 return; 1928 1929 std::set<std::string> enabled_experiments; 1930 1931 GetSanitizedEnabledFlagsForCurrentPlatform(flags_storage, 1932 &enabled_experiments); 1933 1934 NameToSwitchAndValueMap name_to_switch_map; 1935 for (size_t i = 0; i < num_experiments; ++i) { 1936 const Experiment& e = experiments[i]; 1937 if (e.type == Experiment::SINGLE_VALUE) { 1938 SetFlagToSwitchMapping(e.internal_name, e.command_line_switch, 1939 e.command_line_value, &name_to_switch_map); 1940 } else if (e.type == Experiment::MULTI_VALUE) { 1941 for (int j = 0; j < e.num_choices; ++j) { 1942 SetFlagToSwitchMapping(e.NameForChoice(j), 1943 e.choices[j].command_line_switch, 1944 e.choices[j].command_line_value, 1945 &name_to_switch_map); 1946 } 1947 } else { 1948 DCHECK_EQ(e.type, Experiment::ENABLE_DISABLE_VALUE); 1949 SetFlagToSwitchMapping(e.NameForChoice(0), std::string(), std::string(), 1950 &name_to_switch_map); 1951 SetFlagToSwitchMapping(e.NameForChoice(1), e.command_line_switch, 1952 e.command_line_value, &name_to_switch_map); 1953 SetFlagToSwitchMapping(e.NameForChoice(2), e.disable_command_line_switch, 1954 e.disable_command_line_value, &name_to_switch_map); 1955 } 1956 } 1957 1958 command_line->AppendSwitch(switches::kFlagSwitchesBegin); 1959 flags_switches_.insert( 1960 std::pair<std::string, std::string>(switches::kFlagSwitchesBegin, 1961 std::string())); 1962 for (std::set<std::string>::iterator it = enabled_experiments.begin(); 1963 it != enabled_experiments.end(); 1964 ++it) { 1965 const std::string& experiment_name = *it; 1966 NameToSwitchAndValueMap::const_iterator name_to_switch_it = 1967 name_to_switch_map.find(experiment_name); 1968 if (name_to_switch_it == name_to_switch_map.end()) { 1969 NOTREACHED(); 1970 continue; 1971 } 1972 1973 const std::pair<std::string, std::string>& 1974 switch_and_value_pair = name_to_switch_it->second; 1975 1976 command_line->AppendSwitchASCII(switch_and_value_pair.first, 1977 switch_and_value_pair.second); 1978 flags_switches_[switch_and_value_pair.first] = switch_and_value_pair.second; 1979 } 1980 command_line->AppendSwitch(switches::kFlagSwitchesEnd); 1981 flags_switches_.insert( 1982 std::pair<std::string, std::string>(switches::kFlagSwitchesEnd, 1983 std::string())); 1984 } 1985 1986 bool FlagsState::IsRestartNeededToCommitChanges() { 1987 return needs_restart_; 1988 } 1989 1990 void FlagsState::SetExperimentEnabled(FlagsStorage* flags_storage, 1991 const std::string& internal_name, 1992 bool enable) { 1993 size_t at_index = internal_name.find(testing::kMultiSeparator); 1994 if (at_index != std::string::npos) { 1995 DCHECK(enable); 1996 // We're being asked to enable a multi-choice experiment. Disable the 1997 // currently selected choice. 1998 DCHECK_NE(at_index, 0u); 1999 const std::string experiment_name = internal_name.substr(0, at_index); 2000 SetExperimentEnabled(flags_storage, experiment_name, false); 2001 2002 // And enable the new choice, if it is not the default first choice. 2003 if (internal_name != experiment_name + "@0") { 2004 std::set<std::string> enabled_experiments; 2005 GetSanitizedEnabledFlags(flags_storage, &enabled_experiments); 2006 needs_restart_ |= enabled_experiments.insert(internal_name).second; 2007 flags_storage->SetFlags(enabled_experiments); 2008 } 2009 return; 2010 } 2011 2012 std::set<std::string> enabled_experiments; 2013 GetSanitizedEnabledFlags(flags_storage, &enabled_experiments); 2014 2015 const Experiment* e = NULL; 2016 for (size_t i = 0; i < num_experiments; ++i) { 2017 if (experiments[i].internal_name == internal_name) { 2018 e = experiments + i; 2019 break; 2020 } 2021 } 2022 DCHECK(e); 2023 2024 if (e->type == Experiment::SINGLE_VALUE) { 2025 if (enable) 2026 needs_restart_ |= enabled_experiments.insert(internal_name).second; 2027 else 2028 needs_restart_ |= (enabled_experiments.erase(internal_name) > 0); 2029 } else { 2030 if (enable) { 2031 // Enable the first choice. 2032 needs_restart_ |= enabled_experiments.insert(e->NameForChoice(0)).second; 2033 } else { 2034 // Find the currently enabled choice and disable it. 2035 for (int i = 0; i < e->num_choices; ++i) { 2036 std::string choice_name = e->NameForChoice(i); 2037 if (enabled_experiments.find(choice_name) != 2038 enabled_experiments.end()) { 2039 needs_restart_ = true; 2040 enabled_experiments.erase(choice_name); 2041 // Continue on just in case there's a bug and more than one 2042 // experiment for this choice was enabled. 2043 } 2044 } 2045 } 2046 } 2047 2048 flags_storage->SetFlags(enabled_experiments); 2049 } 2050 2051 void FlagsState::RemoveFlagsSwitches( 2052 std::map<std::string, CommandLine::StringType>* switch_list) { 2053 for (std::map<std::string, std::string>::const_iterator 2054 it = flags_switches_.begin(); it != flags_switches_.end(); ++it) { 2055 switch_list->erase(it->first); 2056 } 2057 } 2058 2059 void FlagsState::ResetAllFlags(FlagsStorage* flags_storage) { 2060 needs_restart_ = true; 2061 2062 std::set<std::string> no_experiments; 2063 flags_storage->SetFlags(no_experiments); 2064 } 2065 2066 void FlagsState::reset() { 2067 needs_restart_ = false; 2068 flags_switches_.clear(); 2069 } 2070 2071 } // namespace 2072 2073 namespace testing { 2074 2075 // WARNING: '@' is also used in the html file. If you update this constant you 2076 // also need to update the html file. 2077 const char kMultiSeparator[] = "@"; 2078 2079 void ClearState() { 2080 FlagsState::GetInstance()->reset(); 2081 } 2082 2083 void SetExperiments(const Experiment* e, size_t count) { 2084 if (!e) { 2085 experiments = kExperiments; 2086 num_experiments = arraysize(kExperiments); 2087 } else { 2088 experiments = e; 2089 num_experiments = count; 2090 } 2091 } 2092 2093 const Experiment* GetExperiments(size_t* count) { 2094 *count = num_experiments; 2095 return experiments; 2096 } 2097 2098 } // namespace testing 2099 2100 } // namespace about_flags 2101