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