Added --force-ui-direction flag for developers to force LTR or RTL.

Setting this flag to ltr or rtl will force the system-wide text
direction to the chosen direction. This allows developers to test RTL
layouts without having to actually switch their language to Hebrew or
Arabic.

BUG=558208

Review URL: https://codereview.chromium.org/1458043003

Cr-Commit-Position: refs/heads/master@{#363135}
diff --git a/base/BUILD.gn b/base/BUILD.gn
index e5f3c196..2d1e5a33 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1005,6 +1005,8 @@
   output_name = "base_i18n"
   sources = [
     "i18n/base_i18n_export.h",
+    "i18n/base_i18n_switches.cc",
+    "i18n/base_i18n_switches.h",
     "i18n/bidi_line_iterator.cc",
     "i18n/bidi_line_iterator.h",
     "i18n/break_iterator.cc",
diff --git a/base/base.gypi b/base/base.gypi
index 35bd747..3ad9ccf 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -1018,6 +1018,8 @@
         ],
         'sources': [
           'i18n/base_i18n_export.h',
+          'i18n/base_i18n_switches.cc',
+          'i18n/base_i18n_switches.h',
           'i18n/bidi_line_iterator.cc',
           'i18n/bidi_line_iterator.h',
           'i18n/break_iterator.cc',
diff --git a/base/i18n/base_i18n_switches.cc b/base/i18n/base_i18n_switches.cc
new file mode 100644
index 0000000..44e8393
--- /dev/null
+++ b/base/i18n/base_i18n_switches.cc
@@ -0,0 +1,16 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/i18n/base_i18n_switches.h"
+
+namespace switches {
+
+// Force the UI to a specific direction. Valid values are "ltr" (left-to-right)
+// and "rtl" (right-to-left).
+const char kForceUIDirection[]              = "force-ui-direction";
+
+const char kForceUIDirectionLTR[]           = "ltr";
+const char kForceUIDirectionRTL[]           = "rtl";
+
+}  // namespace switches
diff --git a/base/i18n/base_i18n_switches.h b/base/i18n/base_i18n_switches.h
new file mode 100644
index 0000000..f00cff3
--- /dev/null
+++ b/base/i18n/base_i18n_switches.h
@@ -0,0 +1,20 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_I18N_BASE_I18N_SWITCHES_H_
+#define BASE_I18N_BASE_I18N_SWITCHES_H_
+
+#include "base/i18n/base_i18n_export.h"
+
+namespace switches {
+
+BASE_I18N_EXPORT extern const char kForceUIDirection[];
+
+// kForceUIDirection choices.
+BASE_I18N_EXPORT extern const char kForceUIDirectionLTR[];
+BASE_I18N_EXPORT extern const char kForceUIDirectionRTL[];
+
+}  // namespace switches
+
+#endif  // BASE_I18N_BASE_I18N_SWITCHES_H_
diff --git a/base/i18n/rtl.cc b/base/i18n/rtl.cc
index ac9589c..adcf6deb 100644
--- a/base/i18n/rtl.cc
+++ b/base/i18n/rtl.cc
@@ -6,7 +6,9 @@
 
 #include <algorithm>
 
+#include "base/command_line.h"
 #include "base/files/file_path.h"
+#include "base/i18n/base_i18n_switches.h"
 #include "base/logging.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
@@ -64,6 +66,30 @@
   return base::i18n::UNKNOWN_DIRECTION;
 }
 
+// Gets the explicitly forced text direction for debugging. If no forcing is
+// applied, returns UNKNOWN_DIRECTION.
+base::i18n::TextDirection GetForcedTextDirection() {
+  // On iOS, check for RTL forcing.
+#if defined(OS_IOS)
+  if (base::ios::IsInForcedRTL())
+    return base::i18n::RIGHT_TO_LEFT;
+#endif
+
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(switches::kForceUIDirection)) {
+    std::string force_flag =
+        command_line->GetSwitchValueASCII(switches::kForceUIDirection);
+
+    if (force_flag == switches::kForceUIDirectionLTR)
+      return base::i18n::LEFT_TO_RIGHT;
+
+    if (force_flag == switches::kForceUIDirectionRTL)
+      return base::i18n::RIGHT_TO_LEFT;
+  }
+
+  return base::i18n::UNKNOWN_DIRECTION;
+}
+
 }  // namespace
 
 namespace base {
@@ -135,11 +161,10 @@
 }
 
 TextDirection GetTextDirectionForLocaleInStartUp(const char* locale_name) {
-// On iOS, check for RTL forcing.
-#if defined(OS_IOS)
-  if (ios::IsInForcedRTL())
-    return RIGHT_TO_LEFT;
-#endif
+  // Check for direction forcing.
+  TextDirection forced_direction = GetForcedTextDirection();
+  if (forced_direction != UNKNOWN_DIRECTION)
+    return forced_direction;
 
   // This list needs to be updated in alphabetical order if we add more RTL
   // locales.
@@ -155,11 +180,10 @@
 }
 
 TextDirection GetTextDirectionForLocale(const char* locale_name) {
-  // On iOS, check for RTL forcing.
-#if defined(OS_IOS)
-  if (ios::IsInForcedRTL())
-    return RIGHT_TO_LEFT;
-#endif
+  // Check for direction forcing.
+  TextDirection forced_direction = GetForcedTextDirection();
+  if (forced_direction != UNKNOWN_DIRECTION)
+    return forced_direction;
 
   UErrorCode status = U_ZERO_ERROR;
   ULayoutType layout_dir = uloc_getCharacterOrientation(locale_name, &status);
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 02c94cd..1548f7a 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6681,6 +6681,18 @@
           Enables a new option to upload credit cards to Google Payments for sync to all Chrome devices.
         </message>
       </if>
+      <message name="IDS_FLAGS_FORCE_UI_DIRECTION_NAME" desc="Name for the flag to force a specific UI direction.">
+          Force UI direction
+      </message>
+      <message name="IDS_FLAGS_FORCE_UI_DIRECTION_DESCRIPTION" desc="Description for the flag to force a specific UI direction.">
+          Explicitly force the UI to left-to-right or right-to-left mode, overriding the default direction of the UI language.
+      </message>
+      <message name="IDS_FLAGS_FORCE_UI_DIRECTION_LTR" desc="Name for the option to force left-to-right UI direction mode.">
+          Left-to-right
+      </message>
+      <message name="IDS_FLAGS_FORCE_UI_DIRECTION_RTL" desc="Name for the option to force right-to-left UI direction mode.">
+          Right-to-left
+      </message>
 
       <!-- WebRTC logs -->
       <message name="IDS_WEBRTC_LOGS_TITLE" desc="Title for the chrome://webrtc-logs page.">
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index e5d3c8b..0b32f781 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -13,6 +13,7 @@
 #include "base/callback.h"
 #include "base/command_line.h"
 #include "base/feature_list.h"
+#include "base/i18n/base_i18n_switches.h"
 #include "base/memory/singleton.h"
 #include "base/metrics/metrics_hashes.h"
 #include "base/metrics/sparse_histogram.h"
@@ -513,6 +514,14 @@
 };
 #endif  // defined(OS_WIN)
 
+const FeatureEntry::Choice kForceUIDirectionChoices[] = {
+    {IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", ""},
+    {IDS_FLAGS_FORCE_UI_DIRECTION_LTR, switches::kForceUIDirection,
+     switches::kForceUIDirectionLTR},
+    {IDS_FLAGS_FORCE_UI_DIRECTION_RTL, switches::kForceUIDirection,
+     switches::kForceUIDirectionRTL},
+};
+
 // RECORDING USER METRICS FOR FLAGS:
 // -----------------------------------------------------------------------------
 // The first line of the entry is the internal name. If you'd like to gather
@@ -2089,6 +2098,11 @@
      kOsWin,
      FEATURE_VALUE_TYPE(kWindowsDesktopSearchRedirectionFeature)},
 #endif  // defined(OS_WIN)
+    {"force-ui-direction",
+     IDS_FLAGS_FORCE_UI_DIRECTION_NAME,
+     IDS_FLAGS_FORCE_UI_DIRECTION_DESCRIPTION,
+     kOsAll,
+     MULTI_VALUE_TYPE(kForceUIDirectionChoices)},
     // NOTE: Adding new command-line switches requires adding corresponding
     // entries to enum "LoginCustomFlags" in histograms.xml. See note in
     // histograms.xml and don't forget to run AboutFlagsHistogramTest unit test.
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 956e217..2b2333a9 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -67653,6 +67653,7 @@
   <int value="-2008272679" label="disable-webrtc-hw-encoding"/>
   <int value="-2003354337"
       label="enable-search-button-in-omnibox-for-str-or-iip"/>
+  <int value="-1999892428" label="force-ui-direction"/>
   <int value="-1998927516" label="enable-md-settings"/>
   <int value="-1985025593" label="file-manager-enable-new-gallery"/>
   <int value="-1980328793" label="trace-upload-url"/>