Bug 1347314 - Migrate calls to ChromeRegistry::GetSelectedLocale to use LocaleService::GetAppLocale. r=jfkthame,Pike
☠☠ backed out by 48e124a57b7f ☠ ☠
authorZibi Braniecki <gandalf@mozilla.com>
Tue, 14 Mar 2017 16:09:54 -0700
changeset 348904 cc308a73ad05ab7b11872d8640f9711a99775094
parent 348903 ca7a7a8800ef4a3080fbfa4507db4fa4c1f8b070
child 348905 a7893368789d872ad4b92610935bbddc47f2df7c
push id31539
push userkwierso@gmail.com
push dateWed, 22 Mar 2017 23:54:52 +0000
treeherdermozilla-central@08b46c736a62 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame, Pike
bugs1347314, 1346674
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1347314 - Migrate calls to ChromeRegistry::GetSelectedLocale to use LocaleService::GetAppLocale. r=jfkthame,Pike In cases, where the caller is looking for the locale to be used for JS Intl API, we can now replace it with `undefined` which causes JS Intl API to use the default locale which since bug 1346674 is resolved to the app locale. This allows us to remove a lot of calls for the app locale. The remaining ones are split between `AsBCP47` and `AsLangTag`. Here, the `AsLangTag` is used, as described in the API docs, for cases where the language string is used for localization purposes, such as language negotaition matching to our language resources etc. `AsBCP47` is used when the returned value is handed over to ICU API. MozReview-Commit-ID: DzmFEUvMq3N
browser/base/content/pageinfo/pageInfo.js
browser/components/customizableui/content/panelUI.js
browser/components/feeds/FeedWriter.js
browser/components/migration/AutoMigrate.jsm
browser/components/places/content/places.js
browser/components/places/content/treeView.js
browser/components/places/tests/chrome/test_treeview_date.xul
browser/components/preferences/cookies.js
browser/components/preferences/in-content/tests/browser_advanced_update.js
browser/components/translation/Translation.jsm
browser/components/translation/translation-infobar.xml
browser/experiments/Experiments.jsm
browser/experiments/docs/manifest.rst
browser/extensions/pocket/content/main.js
browser/extensions/pocket/content/pktApi.jsm
browser/extensions/shield-recipe-client/lib/NormandyDriver.jsm
devtools/client/shared/doorhanger.js
devtools/server/tests/mochitest/test_device.html
devtools/shared/system.js
dom/encoding/FallbackEncoding.cpp
dom/xul/nsXULPrototypeCache.cpp
editor/composer/nsEditorSpellCheck.cpp
intl/unicharutil/util/ICUUtils.cpp
services/sync/tps/extensions/mozmill/resource/driver/mozmill.js
testing/marionette/puppeteer/firefox/firefox_puppeteer/api/appinfo.py
toolkit/components/urlformatter/nsURLFormatter.js
toolkit/components/urlformatter/tests/unit/test_urlformatter.js
toolkit/content/widgets/datetimepopup.xml
toolkit/crashreporter/content/crashes.js
toolkit/mozapps/downloads/DownloadUtils.jsm
toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/content/extensions.xml
toolkit/mozapps/extensions/test/browser/browser_experiments.js
toolkit/mozapps/extensions/test/browser/head.js
toolkit/mozapps/update/content/history.js
uriloader/exthandler/nsHandlerService.js
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -997,22 +997,19 @@ function formatNumber(number) {
   return (+number).toLocaleString();  // coerce number to a numeric value before calling toLocaleString()
 }
 
 function formatDate(datestr, unknown) {
   var date = new Date(datestr);
   if (!date.valueOf())
     return unknown;
 
-  const locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
-                 .getService(Components.interfaces.nsIXULChromeRegistry)
-                 .getSelectedLocale("global", true);
   const dtOptions = { year: "numeric", month: "long", day: "numeric",
                       hour: "numeric", minute: "numeric", second: "numeric" };
-  return date.toLocaleString(locale, dtOptions);
+  return date.toLocaleString(undefined, dtOptions);
 }
 
 function doCopy() {
   if (!gClipboardHelper)
     return;
 
   var elem = document.commandDispatcher.focusedElement;
 
--- a/browser/components/customizableui/content/panelUI.js
+++ b/browser/components/customizableui/content/panelUI.js
@@ -539,19 +539,13 @@ const PanelUI = {
     this._scrollWidth = null;
   },
 };
 
 XPCOMUtils.defineConstant(this, "PanelUI", PanelUI);
 
 /**
  * Gets the currently selected locale for display.
- * @return  the selected locale or "en-US" if none is selected
+ * @return  the selected locale
  */
 function getLocale() {
-  try {
-    let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"]
-                           .getService(Ci.nsIXULChromeRegistry);
-    return chromeRegistry.getSelectedLocale("browser");
-  } catch (ex) {
-    return "en-US";
-  }
+  return Services.locale.getAppLocaleAsLangTag();
 }
--- a/browser/components/feeds/FeedWriter.js
+++ b/browser/components/feeds/FeedWriter.js
@@ -184,22 +184,19 @@ FeedWriter.prototype = {
       return false;
 
     return this._dateFormatter.format(dateObj);
   },
 
   __dateFormatter: null,
   get _dateFormatter() {
     if (!this.__dateFormatter) {
-      const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
-                     .getService(Ci.nsIXULChromeRegistry)
-                     .getSelectedLocale("global", true);
       const dtOptions = { year: "numeric", month: "long", day: "numeric",
                           hour: "numeric", minute: "numeric" };
-      this.__dateFormatter = new Intl.DateTimeFormat(locale, dtOptions);
+      this.__dateFormatter = new Intl.DateTimeFormat(undefined, dtOptions);
     }
     return this.__dateFormatter;
   },
 
   /**
    * Returns the feed type.
    */
   __feedType: null,
--- a/browser/components/migration/AutoMigrate.jsm
+++ b/browser/components/migration/AutoMigrate.jsm
@@ -633,20 +633,18 @@ const AutoMigrate = {
   _maybeOpenUndoSurveyTab(chromeWindow) {
     let canDoSurveyInLocale = false;
     try {
       let surveyLocales = Preferences.get(kAutoMigrateUndoSurveyLocalePref, "");
       surveyLocales = surveyLocales.split(",").map(str => str.trim());
       // Strip out any empty elements, so an empty pref doesn't
       // lead to a an array with 1 empty string in it.
       surveyLocales = new Set(surveyLocales.filter(str => !!str));
-      let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"]
-                             .getService(Ci.nsIXULChromeRegistry);
       canDoSurveyInLocale =
-        surveyLocales.has(chromeRegistry.getSelectedLocale("global"));
+        surveyLocales.has(Services.locale.getAppLocaleAsLangTag());
     } catch (ex) {
       /* ignore exceptions and just don't do the survey. */
     }
 
     let migrationBrowser = this.getBrowserUsedForMigration();
     let rawURL = Preferences.get(kAutoMigrateUndoSurveyPref, "");
     if (!canDoSurveyInLocale || !migrationBrowser || !rawURL) {
       return;
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -406,21 +406,18 @@ var PlacesOrganizer = {
   },
 
   /**
    * Populates the restore menu with the dates of the backups available.
    */
   populateRestoreMenu: function PO_populateRestoreMenu() {
     let restorePopup = document.getElementById("fileRestorePopup");
 
-    const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
-                   .getService(Ci.nsIXULChromeRegistry)
-                   .getSelectedLocale("global", true);
     const dtOptions = { year: "numeric", month: "long", day: "numeric" };
-    let dateFormatter = new Intl.DateTimeFormat(locale, dtOptions);
+    let dateFormatter = new Intl.DateTimeFormat(undefined, dtOptions);
 
     // Remove existing menu items.  Last item is the restoreFromFile item.
     while (restorePopup.childNodes.length > 1)
       restorePopup.firstChild.remove();
 
     Task.spawn(function* () {
       let backupFiles = yield PlacesBackups.getBackupFiles();
       if (backupFiles.length == 0)
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -494,34 +494,28 @@ PlacesTreeView.prototype = {
                               : this._dateFormatter.format(timeObj);
   },
 
   // We use a different formatter for times within the current day,
   // so we cache both a "today" formatter and a general date formatter.
   __todayFormatter: null,
   get _todayFormatter() {
     if (!this.__todayFormatter) {
-      const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
-                     .getService(Ci.nsIXULChromeRegistry)
-                     .getSelectedLocale("global", true);
       const dtOptions = { hour: "numeric", minute: "numeric" };
-      this.__todayFormatter = new Intl.DateTimeFormat(locale, dtOptions);
+      this.__todayFormatter = new Intl.DateTimeFormat(undefined, dtOptions);
     }
     return this.__todayFormatter;
   },
 
   __dateFormatter: null,
   get _dateFormatter() {
     if (!this.__dateFormatter) {
-      const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
-                     .getService(Ci.nsIXULChromeRegistry)
-                     .getSelectedLocale("global", true);
       const dtOptions = { year: "numeric", month: "numeric", day: "numeric",
                           hour: "numeric", minute: "numeric" };
-      this.__dateFormatter = new Intl.DateTimeFormat(locale, dtOptions);
+      this.__dateFormatter = new Intl.DateTimeFormat(undefined, dtOptions);
     }
     return this.__dateFormatter;
   },
 
   COLUMN_TYPE_UNKNOWN: 0,
   COLUMN_TYPE_TITLE: 1,
   COLUMN_TYPE_URI: 2,
   COLUMN_TYPE_DATE: 3,
--- a/browser/components/places/tests/chrome/test_treeview_date.xul
+++ b/browser/components/places/tests/chrome/test_treeview_date.xul
@@ -99,19 +99,16 @@
         tree.place = queryURI;
 
         // loop through the rows and check formatting
         let treeView = tree.view;
         let rc = treeView.rowCount;
         ok(rc >= 3, "Rows found");
         let columns = tree.columns;
         ok(columns.count > 0, "Columns found");
-        const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
-                       .getService(Ci.nsIXULChromeRegistry)
-                       .getSelectedLocale("global", true);
         for (let r = 0; r < rc; r++) {
           let node = treeView.nodeForTreeIndex(r);
           ok(node, "Places node found");
           for (let ci = 0; ci < columns.count; ci++) {
             let c = columns.getColumnAt(ci);
             let text = treeView.getCellText(r, c);
             switch (c.element.getAttribute("anonid")) {
               case "title":
@@ -133,17 +130,17 @@
                 if (node.uri == "http://at.midnight.com/" ||
                     node.uri == "http://after.midnight.com/") {
                   dtOptions = { hour: 'numeric', minute: 'numeric' };
                 } else if (node.uri != "http://before.midnight.com/") {
                   // Avoid to test spurious uris, due to how the test works
                   // a redirecting uri could be put in the tree while we test.
                   break;
                 }
-                let timeStr = timeObj.toLocaleString(locale, dtOptions);
+                let timeStr = timeObj.toLocaleString(undefined, dtOptions);
 
                 is(text, timeStr, "Date format is correct");
                 break;
               case "visitCount":
                 is(text, 1, "Visit count is correct");
                 break;
             }
           }
--- a/browser/components/preferences/cookies.js
+++ b/browser/components/preferences/cookies.js
@@ -492,22 +492,19 @@ var gCookiesWindow = {
         break;
     }
     this._view._rowCount = hostCount.value;
   },
 
   formatExpiresString(aExpires) {
     if (aExpires) {
       var date = new Date(1000 * aExpires);
-      const locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
-                     .getService(Components.interfaces.nsIXULChromeRegistry)
-                     .getSelectedLocale("global", true);
       const dtOptions = { year: "numeric", month: "long", day: "numeric",
                           hour: "numeric", minute: "numeric", second: "numeric" };
-      return date.toLocaleString(locale, dtOptions);
+      return date.toLocaleString(undefined, dtOptions);
     }
     return this._bundle.getString("expireAtEndOfSession");
   },
 
   _getUserContextString(aUserContextId) {
     if (parseInt(aUserContextId) == 0) {
       return this._bundle.getString("defaultUserContextLabel");
     }
--- a/browser/components/preferences/in-content/tests/browser_advanced_update.js
+++ b/browser/components/preferences/in-content/tests/browser_advanced_update.js
@@ -80,22 +80,19 @@ const mockUpdateManager = {
 };
 
 function resetPreferences() {
   Services.prefs.clearUserPref("browser.search.update");
 }
 
 function formatInstallDate(sec) {
   var date = new Date(sec);
-  const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
-                 .getService(Ci.nsIXULChromeRegistry)
-                 .getSelectedLocale("global", true);
   const dtOptions = { year: "numeric", month: "long", day: "numeric",
                       hour: "numeric", minute: "numeric", second: "numeric" };
-  return date.toLocaleString(locale, dtOptions);
+  return date.toLocaleString(undefined, dtOptions);
 }
 
 registerCleanupFunction(resetPreferences);
 
 add_task(function*() {
   yield openPreferencesViaOpenPreferencesAPI("advanced", "updateTab", { leaveOpen: true });
   resetPreferences();
   Services.prefs.setBoolPref("browser.search.update", false);
--- a/browser/components/translation/Translation.jsm
+++ b/browser/components/translation/Translation.jsm
@@ -28,19 +28,17 @@ this.Translation = {
   serviceUnavailable: false,
 
   supportedSourceLanguages: ["bg", "cs", "de", "en", "es", "fr", "ja", "ko", "nl", "no", "pl", "pt", "ru", "tr", "vi", "zh"],
   supportedTargetLanguages: ["bg", "cs", "de", "en", "es", "fr", "ja", "ko", "nl", "no", "pl", "pt", "ru", "tr", "vi", "zh"],
 
   _defaultTargetLanguage: "",
   get defaultTargetLanguage() {
     if (!this._defaultTargetLanguage) {
-      this._defaultTargetLanguage = Cc["@mozilla.org/chrome/chrome-registry;1"]
-                                      .getService(Ci.nsIXULChromeRegistry)
-                                      .getSelectedLocale("global")
+      this._defaultTargetLanguage = Services.locale.getAppLocaleAsLangTag()
                                       .split("-")[0];
     }
     return this._defaultTargetLanguage;
   },
 
   documentStateReceived(aBrowser, aData) {
     if (aData.state == this.STATE_OFFER) {
       if (aData.detectedLanguage == this.defaultTargetLanguage) {
--- a/browser/components/translation/translation-infobar.xml
+++ b/browser/components/translation/translation-infobar.xml
@@ -259,19 +259,17 @@
                      "Daha fazla bilgi al\u0131n.",
                      "Te\u015Fekk\xFCrler"],
                 vi: ["Nh\xECn n\xE0y! \u0110\u1ED3 m\u1EDBi!",
                      "Gi\u1EDD \u0111\xE2y ch\xFAng ta c\xF3 th\u1EC3 ti\u1EBFp c\u1EADn web d\u1EC5 d\xE0ng h\u01A1n n\u1EEFa v\u1EDBi t\xEDnh n\u0103ng d\u1ECBch ngay trong trang.  Hay nh\u1EA5n n\xFAt d\u1ECBch \u0111\u1EC3 th\u1EED!",
                      "T\xECm hi\u1EC3u th\xEAm.",
                      "C\u1EA3m \u01A1n"]
               };
 
-              let locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
-                             .getService(Ci.nsIXULChromeRegistry)
-                             .getSelectedLocale("browser");
+              let locale = Services.locale.getAppLocaleAsLangTag();
               if (!(locale in localizedStrings))
                 locale = "en";
               let strings = localizedStrings[locale];
 
               this._getAnonElt("welcomeHeadline").setAttribute("value", strings[0]);
               this._getAnonElt("welcomeBody").textContent = strings[1];
               this._getAnonElt("learnMore").setAttribute("value", strings[2]);
               this._getAnonElt("thanksButton").setAttribute("label", strings[3]);
--- a/browser/experiments/Experiments.jsm
+++ b/browser/experiments/Experiments.jsm
@@ -264,18 +264,17 @@ Experiments.Policy.prototype = {
     return CommonUtils.namedTimer(callback, timeout, thisObj, name);
   },
 
   updatechannel() {
     return UpdateUtils.UpdateChannel;
   },
 
   locale() {
-    let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry);
-    return chrome.getSelectedLocale("global");
+    return Services.locale.getAppLocaleAsLangTag();
   },
 
   /**
    * For testing a race condition, one of the tests delays the callback of
    * writing the cache by replacing this policy function.
    */
   delayCacheWrite(promise) {
     return promise;
--- a/browser/experiments/docs/manifest.rst
+++ b/browser/experiments/docs/manifest.rst
@@ -189,17 +189,19 @@ channel
    If this property is not defined, the client should assume the experiment
    is to run on all channels.
 
 locale
    (optional) Array of locale identifiers this experiment should run on.
 
    A locale identifier is a string like ``en-US`` or ``zh-CN`` and is
    obtained by looking at
-   ``nsIXULChromeRegistry.getSelectedLocale("global")``.
+   ``LocaleService.getAppLocaleAsLangTag()``.
+   For infamous `ja-JP-mac` case, this will return it in
+   the language tag form (`ja-JP-mac`).
 
    The client should compare its locale identifier to members of this array.
    If a match is found, the experiment is applicable.
 
    If this property is not defined, the client should assume the experiment
    is to run on all locales.
 
 sample
--- a/browser/extensions/pocket/content/main.js
+++ b/browser/extensions/pocket/content/main.js
@@ -565,20 +565,17 @@ var pktUI = (function() {
         fxAccounts.getSignedInUser().then(userData => {
             callback(userData);
         }).then(null, error => {
             callback();
         });
     }
 
     function getUILocale() {
-        var locale = Cc["@mozilla.org/chrome/chrome-registry;1"].
-             getService(Ci.nsIXULChromeRegistry).
-             getSelectedLocale("browser");
-        return locale;
+        return Services.locale.getAppLocaleAsLangTag();
     }
 
     /**
      * Public functions
      */
     return {
         getPanelFrame,
 
--- a/browser/extensions/pocket/content/pktApi.jsm
+++ b/browser/extensions/pocket/content/pktApi.jsm
@@ -245,19 +245,17 @@ var pktApi = (function() {
     */
     function apiRequest(options) {
         if ((typeof options === "undefined") || (typeof options.path === "undefined")) {
             return false;
         }
 
         var url = baseAPIUrl + options.path;
         var data = options.data || {};
-        data.locale_lang = Cc["@mozilla.org/chrome/chrome-registry;1"].
-             getService(Ci.nsIXULChromeRegistry).
-             getSelectedLocale("browser");
+        data.locale_lang = Services.locale.getAppLocaleAsLangTag();
         data.consumer_key = oAuthConsumerKey;
 
         var request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Components.interfaces.nsIXMLHttpRequest);
         request.open("POST", url, true);
         request.onreadystatechange = function(e) {
             if (request.readyState == 4) {
                 if (request.status === 200) {
                     // There could still be an error if the response is no valid json
--- a/browser/extensions/shield-recipe-client/lib/NormandyDriver.jsm
+++ b/browser/extensions/shield-recipe-client/lib/NormandyDriver.jsm
@@ -29,19 +29,17 @@ this.NormandyDriver = function(sandboxMa
     throw new Error("sandboxManager is required");
   }
   const {sandbox} = sandboxManager;
 
   return {
     testing: false,
 
     get locale() {
-      return Cc["@mozilla.org/chrome/chrome-registry;1"]
-        .getService(Ci.nsIXULChromeRegistry)
-        .getSelectedLocale("browser");
+      return Services.locale.getAppLocaleAsLangTag();
     },
 
     get userId() {
       return EnvExpressions.getUserId();
     },
 
     log(message, level = "debug") {
       const levels = ["debug", "info", "warn", "error"];
--- a/devtools/client/shared/doorhanger.js
+++ b/devtools/client/shared/doorhanger.js
@@ -1,39 +1,35 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-const { Ci, Cc } = require("chrome");
 const Services = require("Services");
 const { DOMHelpers } = require("resource://devtools/client/shared/DOMHelpers.jsm");
 const { Task } = require("devtools/shared/task");
 const defer = require("devtools/shared/defer");
 const { getMostRecentBrowserWindow } = require("sdk/window/utils");
 
 const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 const DEV_EDITION_PROMO_URL = "chrome://devtools/content/framework/dev-edition-promo/dev-edition-promo.xul";
 const DEV_EDITION_PROMO_ENABLED_PREF = "devtools.devedition.promo.enabled";
 const DEV_EDITION_PROMO_SHOWN_PREF = "devtools.devedition.promo.shown";
 const DEV_EDITION_PROMO_URL_PREF = "devtools.devedition.promo.url";
-const LOCALE = Cc["@mozilla.org/chrome/chrome-registry;1"]
-               .getService(Ci.nsIXULChromeRegistry)
-               .getSelectedLocale("global");
 
 /**
  * Only show Dev Edition promo if it's enabled (beta channel),
  * if it has not been shown before, and it's a locale build
  * for `en-US`
  */
 function shouldDevEditionPromoShow() {
   return Services.prefs.getBoolPref(DEV_EDITION_PROMO_ENABLED_PREF) &&
          !Services.prefs.getBoolPref(DEV_EDITION_PROMO_SHOWN_PREF) &&
-         LOCALE === "en-US";
+         Services.locale.getAppLocaleAsLangTag() === "en-US";
 }
 
 var TYPES = {
   // The Developer Edition promo doorhanger, called by
   // opening the toolbox, browser console, WebIDE, or responsive design mode
   // in Beta releases. Only displayed once per profile.
   deveditionpromo: {
     predicate: shouldDevEditionPromoShow,
--- a/devtools/server/tests/mochitest/test_device.html
+++ b/devtools/server/tests/mochitest/test_device.html
@@ -49,18 +49,17 @@ window.onload = function () {
         name: appInfo.name,
         version: appInfo.version,
         appbuildid: appInfo.appBuildID,
         platformbuildid: appInfo.platformBuildID,
         platformversion: appInfo.platformVersion,
         geckobuildid: appInfo.platformBuildID,
         geckoversion: appInfo.platformVersion,
         useragent: window.navigator.userAgent,
-        locale: Cc["@mozilla.org/chrome/chrome-registry;1"]
-                .getService(Ci.nsIXULChromeRegistry).getSelectedLocale("global"),
+        locale: Services.locale.getAppLocaleAsLangTag(),
         os: appInfo.OS,
         processor: appInfo.XPCOMABI.split("-")[0],
         compiler: appInfo.XPCOMABI.split("-")[1],
         dpi: utils.displayDPI,
         width: window.screen.width,
         height: window.screen.height
       };
 
--- a/devtools/shared/system.js
+++ b/devtools/shared/system.js
@@ -127,18 +127,17 @@ function* getSystemInfo() {
 
     // The version of Gecko or XULRunner platform, for example "1.8.1.19" or
     // "1.9.3pre". In "Firefox 3.7 alpha 1" the application version is "3.7a1pre"
     // while the platform version is "1.9.3pre"
     platformversion: geckoVersion,
     geckoversion: geckoVersion,
 
     // Locale used in this build
-    locale: Cc["@mozilla.org/chrome/chrome-registry;1"]
-              .getService(Ci.nsIXULChromeRegistry).getSelectedLocale("global"),
+    locale: Services.locale.getAppLocaleAsLangTag(),
 
     /**
      * Information regarding the operating system.
      */
 
     // Returns the endianness of the architecture: either "LE" or "BE"
     endianness: OS.endianness(),
 
--- a/dom/encoding/FallbackEncoding.cpp
+++ b/dom/encoding/FallbackEncoding.cpp
@@ -3,19 +3,21 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/FallbackEncoding.h"
 
 #include "mozilla/dom/EncodingUtils.h"
 #include "nsUConvPropertySearch.h"
-#include "nsIChromeRegistry.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
+#include "mozilla/intl/LocaleService.h"
+
+using mozilla::intl::LocaleService;
 
 namespace mozilla {
 namespace dom {
 
 static constexpr nsUConvProp localesFallbacks[] = {
 #include "localesfallbacks.properties.h"
 };
 
@@ -61,21 +63,17 @@ FallbackEncoding::Get(nsACString& aFallb
   }
 
   if (!mFallback.IsEmpty()) {
     aFallback = mFallback;
     return;
   }
 
   nsAutoCString locale;
-  nsCOMPtr<nsIXULChromeRegistry> registry =
-    mozilla::services::GetXULChromeRegistryService();
-  if (registry) {
-    registry->GetSelectedLocale(NS_LITERAL_CSTRING("global"), false, locale);
-  }
+  LocaleService::GetInstance()->GetAppLocaleAsLangTag(locale);
 
   // Let's lower case the string just in case unofficial language packs
   // don't stick to conventions.
   ToLowerCase(locale); // ASCII lowercasing with CString input!
 
   // Special case Traditional Chinese before throwing away stuff after the
   // language itself. Today we only ship zh-TW, but be defensive about
   // possible future values.
--- a/dom/xul/nsXULPrototypeCache.cpp
+++ b/dom/xul/nsXULPrototypeCache.cpp
@@ -6,36 +6,37 @@
 
 #include "nsXULPrototypeCache.h"
 
 #include "plstr.h"
 #include "nsXULPrototypeDocument.h"
 #include "nsIServiceManager.h"
 #include "nsIURI.h"
 
-#include "nsIChromeRegistry.h"
 #include "nsIFile.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsIObserverService.h"
 #include "nsIStringStream.h"
 #include "nsIStorageStream.h"
 
 #include "nsAppDirectoryServiceDefs.h"
 
 #include "js/TracingAPI.h"
 
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/scache/StartupCache.h"
 #include "mozilla/scache/StartupCacheUtils.h"
 #include "mozilla/Telemetry.h"
+#include "mozilla/intl/LocaleService.h"
 
 using namespace mozilla;
 using namespace mozilla::scache;
+using mozilla::intl::LocaleService;
 
 static bool gDisableXULCache = false; // enabled by default
 static const char kDisableXULCachePref[] = "nglayout.debug.disable_xul_cache";
 static const char kXULCacheInfoKey[] = "nsXULPrototypeCache.startupCache";
 static const char kXULCachePrefix[] = "xulcache";
 
 //----------------------------------------------------------------------
 
@@ -494,22 +495,18 @@ nsXULPrototypeCache::BeginCaching(nsIURI
         return rv;
 
     // XXXbe we assume the first package's locale is the same as the locale of
     // all subsequent packages of cached chrome URIs....
     nsAutoCString package;
     rv = aURI->GetHost(package);
     if (NS_FAILED(rv))
         return rv;
-    nsCOMPtr<nsIXULChromeRegistry> chromeReg
-        = do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &rv);
     nsAutoCString locale;
-    rv = chromeReg->GetSelectedLocale(package, false, locale);
-    if (NS_FAILED(rv))
-        return rv;
+    LocaleService::GetInstance()->GetAppLocaleAsLangTag(locale);
 
     nsAutoCString fileChromePath, fileLocale;
 
     UniquePtr<char[]> buf;
     uint32_t len, amtRead;
     nsCOMPtr<nsIObjectInputStream> objectInput;
 
     rv = startupCache->GetBuffer(kXULCacheInfoKey, &buf, &len);
--- a/editor/composer/nsEditorSpellCheck.cpp
+++ b/editor/composer/nsEditorSpellCheck.cpp
@@ -3,27 +3,26 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <stdlib.h>                     // for getenv
 
 #include "mozilla/Attributes.h"         // for final
 #include "mozilla/Preferences.h"        // for Preferences
-#include "mozilla/Services.h"           // for GetXULChromeRegistryService
 #include "mozilla/dom/Element.h"        // for Element
 #include "mozilla/dom/Selection.h"
+#include "mozilla/intl/LocaleService.h" // for retrieving app locale
 #include "mozilla/mozalloc.h"           // for operator delete, etc
 #include "nsAString.h"                  // for nsAString::IsEmpty, etc
 #include "nsComponentManagerUtils.h"    // for do_CreateInstance
 #include "nsDebug.h"                    // for NS_ENSURE_TRUE, etc
 #include "nsDependentSubstring.h"       // for Substring
 #include "nsEditorSpellCheck.h"
 #include "nsError.h"                    // for NS_ERROR_NOT_INITIALIZED, etc
-#include "nsIChromeRegistry.h"          // for nsIXULChromeRegistry
 #include "nsIContent.h"                 // for nsIContent
 #include "nsIContentPrefService.h"      // for nsIContentPrefService, etc
 #include "nsIContentPrefService2.h"     // for nsIContentPrefService2, etc
 #include "nsIDOMDocument.h"             // for nsIDOMDocument
 #include "nsIDOMElement.h"              // for nsIDOMElement
 #include "nsIDocument.h"                // for nsIDocument
 #include "nsIEditor.h"                  // for nsIEditor
 #include "nsIHTMLEditor.h"              // for nsIHTMLEditor
@@ -44,16 +43,17 @@
 #include "nsString.h"                   // for nsAutoString, nsString, etc
 #include "nsStringFwd.h"                // for nsAFlatString
 #include "nsStyleUtil.h"                // for nsStyleUtil
 #include "nsXULAppAPI.h"                // for XRE_GetProcessType
 #include "nsIPlaintextEditor.h"         // for editor flags
 
 using namespace mozilla;
 using namespace mozilla::dom;
+using mozilla::intl::LocaleService;
 
 class UpdateDictionaryHolder {
   private:
     nsEditorSpellCheck* mSpellCheck;
   public:
     explicit UpdateDictionaryHolder(nsEditorSpellCheck* esc): mSpellCheck(esc) {
       if (mSpellCheck) {
         mSpellCheck->BeginUpdateDictionary();
@@ -911,31 +911,26 @@ nsEditorSpellCheck::DictionaryFetched(Di
 #endif
       rv = TryDictionary (preferredDict, dictList, DICT_NORMAL_COMPARE);
     }
   }
 
   // Priority 4:
   // As next fallback, try the current locale.
   if (NS_FAILED(rv)) {
-    nsCOMPtr<nsIXULChromeRegistry> packageRegistry =
-      mozilla::services::GetXULChromeRegistryService();
+    nsAutoCString utf8DictName;
+    LocaleService::GetInstance()->GetAppLocaleAsLangTag(utf8DictName);
 
-    if (packageRegistry) {
-      nsAutoCString utf8DictName;
-      rv2 = packageRegistry->GetSelectedLocale(NS_LITERAL_CSTRING("global"),
-                                               false, utf8DictName);
-      dictName.Assign(EmptyString());
-      AppendUTF8toUTF16(utf8DictName, dictName);
+    dictName.Assign(EmptyString());
+    AppendUTF8toUTF16(utf8DictName, dictName);
 #ifdef DEBUG_DICT
-      printf("***** Trying locale |%s|\n",
-             NS_ConvertUTF16toUTF8(dictName).get());
+    printf("***** Trying locale |%s|\n",
+           NS_ConvertUTF16toUTF8(dictName).get());
 #endif
-      rv = TryDictionary (dictName, dictList, DICT_COMPARE_CASE_INSENSITIVE);
-    }
+    rv = TryDictionary (dictName, dictList, DICT_COMPARE_CASE_INSENSITIVE);
   }
 
   if (NS_FAILED(rv)) {
   // Still no success.
 
   // Priority 5:
   // If we have a current dictionary, don't try anything else.
     nsAutoString currentDictionary;
--- a/intl/unicharutil/util/ICUUtils.cpp
+++ b/intl/unicharutil/util/ICUUtils.cpp
@@ -2,24 +2,25 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifdef MOZILLA_INTERNAL_API
 #ifdef ENABLE_INTL_API
 
 #include "ICUUtils.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/intl/LocaleService.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
-#include "nsIToolkitChromeRegistry.h"
 #include "nsStringGlue.h"
 #include "unicode/uloc.h"
 #include "unicode/unum.h"
 
 using namespace mozilla;
+using mozilla::intl::LocaleService;
 
 /**
  * This pref just controls whether we format the number with grouping separator
  * characters when the internal value is set or updated. It does not stop the
  * user from typing in a number and using grouping separators.
  */
 static bool gLocaleNumberGroupingEnabled;
 static const char LOCALE_NUMBER_GROUPING_PREF_STR[] = "dom.forms.number.grouping";
@@ -65,27 +66,21 @@ ICUUtils::LanguageTagIterForContent::Get
     if (!lang.IsEmpty()) {
       aBCP47LangTag = NS_ConvertUTF16toUTF8(lang);
       return;
     }
   }
 
   if (mCurrentFallbackIndex < 2) {
     mCurrentFallbackIndex = 2;
-    // Else try the user-agent's locale:
-    nsCOMPtr<nsIToolkitChromeRegistry> cr =
-      mozilla::services::GetToolkitChromeRegistryService();
-    nsAutoCString uaLangTag;
-    if (cr) {
-      cr->GetSelectedLocale(NS_LITERAL_CSTRING("global"), true, uaLangTag);
-    }
-    if (!uaLangTag.IsEmpty()) {
-      aBCP47LangTag = uaLangTag;
-      return;
-    }
+    // Else take the app's locale:
+
+    nsAutoCString appLocale;
+    LocaleService::GetInstance()->GetAppLocaleAsBCP47(aBCP47LangTag);
+    return;
   }
 
   // TODO: Probably not worth it, but maybe have a fourth fallback to using
   // the OS locale?
 
   aBCP47LangTag.Truncate(); // Signal iterator exhausted
 }
 
--- a/services/sync/tps/extensions/mozmill/resource/driver/mozmill.js
+++ b/services/sync/tps/extensions/mozmill/resource/driver/mozmill.js
@@ -107,19 +107,17 @@ function getAddons() {
 }
 
 /**
  * Retrieves application details for the Mozmill report
  *
  * @return {String} JSON data of application details
  */
 function getApplicationDetails() {
-  var locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
-               .getService(Ci.nsIXULChromeRegistry)
-               .getSelectedLocale("global");
+  var locale = Services.locale.getAppLocaleAsLangTag();
 
   // Put all our necessary information into JSON and return it:
   // appinfo, startupinfo, and addons
   var details = {
     application_id: appInfo.ID,
     application_name: Application,
     application_version: appInfo.version,
     application_locale: locale,
--- a/testing/marionette/puppeteer/firefox/firefox_puppeteer/api/appinfo.py
+++ b/testing/marionette/puppeteer/firefox/firefox_puppeteer/api/appinfo.py
@@ -25,19 +25,19 @@ class AppInfo(BaseLib):
             else:
                 raise AttributeError('{} has no attribute {}'.format(self.__class__.__name__,
                                                                      attr))
 
     @property
     def locale(self):
         with self.marionette.using_context('chrome'):
             return self.marionette.execute_script("""
-              return Components.classes["@mozilla.org/chrome/chrome-registry;1"]
-                               .getService(Components.interfaces.nsIXULChromeRegistry)
-                               .getSelectedLocale("global");
+              return Components.classes["@mozilla.org/intl/localeservice;1"]
+                               .getService(Components.interfaces.mozILocaleService)
+                               .getAppLocaleAsLangTag();
             """)
 
     @property
     def user_agent(self):
         with self.marionette.using_context('chrome'):
             return self.marionette.execute_script("""
               return Components.classes["@mozilla.org/network/protocol;1?name=http"]
                                .getService(Components.interfaces.nsIHttpProtocolHandler)
--- a/toolkit/components/urlformatter/nsURLFormatter.js
+++ b/toolkit/components/urlformatter/nsURLFormatter.js
@@ -83,19 +83,17 @@ function nsURLFormatterService() {
   });
 }
 
 nsURLFormatterService.prototype = {
   classID: Components.ID("{e6156350-2be8-11db-a98b-0800200c9a66}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIURLFormatter]),
 
   _defaults: {
-    LOCALE:           () => Cc["@mozilla.org/chrome/chrome-registry;1"].
-                            getService(Ci.nsIXULChromeRegistry).
-                            getSelectedLocale('global'),
+    LOCALE:           () => Services.locale.getAppLocaleAsLangTag(),
     REGION:           function() {
       try {
         // When the geoip lookup failed to identify the region, we fallback to
         // the 'ZZ' region code to mean 'unknown'.
         return Services.prefs.getCharPref("browser.search.region") || "ZZ";
       } catch(e) {
         return "ZZ";
       }
--- a/toolkit/components/urlformatter/tests/unit/test_urlformatter.js
+++ b/toolkit/components/urlformatter/tests/unit/test_urlformatter.js
@@ -1,17 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 function run_test() {
   var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
                   getService(Ci.nsIURLFormatter);
-  var locale = Cc["@mozilla.org/chrome/chrome-registry;1"].
-               getService(Ci.nsIXULChromeRegistry).
-               getSelectedLocale("global");
+  var locale = Cc["@mozilla.org/intl/localeservice;1"].
+               getService(Ci.mozILocaleService).
+               getAppLocaleAsLangTag();
   var prefs = Cc["@mozilla.org/preferences-service;1"].
               getService(Ci.nsIPrefBranch);
   var sysInfo = Cc["@mozilla.org/system-info;1"].
                 getService(Ci.nsIPropertyBag2);
   var OSVersion = sysInfo.getProperty("name") + " " +
                   sysInfo.getProperty("version");
   try {
     OSVersion += " (" + sysInfo.getProperty("secondaryLibrary") + ")";
--- a/toolkit/content/widgets/datetimepopup.xml
+++ b/toolkit/content/widgets/datetimepopup.xml
@@ -93,17 +93,17 @@
               break;
             }
           }
         ]]></body>
       </method>
       <method name="initPicker">
         <parameter name="detail"/>
         <body><![CDATA[
-          const locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).getSelectedLocale("global");
+          const locale = Services.locale.getAppLocaleAsBCP47();
           const dir = this.mozIntl.getLocaleInfo(locale).direction;
 
           switch (this.type) {
             case "time": {
               const { hour, minute } = detail.value;
               const format = detail.format || "12";
 
               this.postMessageToPicker({
--- a/toolkit/crashreporter/content/crashes.js
+++ b/toolkit/crashreporter/content/crashes.js
@@ -75,24 +75,21 @@ function populateReportList() {
     document.getElementById("reportList").style.display = "none";
     document.getElementById("noReports").style.display = "block";
     return;
   }
 
   var dateFormatter;
   var timeFormatter;
   try {
-    const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
-                   .getService(Ci.nsIXULChromeRegistry)
-                   .getSelectedLocale("global", true);
-    dateFormatter = new Intl.DateTimeFormat(locale, { year: "2-digit",
-                                                      month: "numeric",
-                                                      day: "numeric" });
-    timeFormatter = new Intl.DateTimeFormat(locale, { hour: "numeric",
-                                                      minute: "numeric" });
+    dateFormatter = new Intl.DateTimeFormat(undefined, { year: "2-digit",
+                                                         month: "numeric",
+                                                         day: "numeric" });
+    timeFormatter = new Intl.DateTimeFormat(undefined, { hour: "numeric",
+                                                         minute: "numeric" });
   } catch (e) {
     // XXX Fallback to be removed once bug 1215247 is complete
     // and the Intl API is available on all platforms.
     dateFormatter = {
       format(date) {
         return date.toLocaleDateString();
       }
     }
--- a/toolkit/mozapps/downloads/DownloadUtils.jsm
+++ b/toolkit/mozapps/downloads/DownloadUtils.jsm
@@ -343,46 +343,38 @@ this.DownloadUtils = {
     }
 
     let dts = Cc["@mozilla.org/intl/scriptabledateformat;1"]
               .getService(Ci.nsIScriptableDateFormat);
 
     // Figure out when today begins
     let today = new Date(aNow.getFullYear(), aNow.getMonth(), aNow.getDate());
 
-    // Get locale to use for date/time formatting
-    // TODO: Remove Intl fallback when no longer needed (bug 1344543).
-    const locale = typeof Intl === "undefined"
-                   ? undefined
-                   : Cc["@mozilla.org/chrome/chrome-registry;1"]
-                       .getService(Ci.nsIXULChromeRegistry)
-                       .getSelectedLocale("global", true);
-
     // Figure out if the time is from today, yesterday, this week, etc.
     let dateTimeCompact;
     if (aDate >= today) {
       // After today started, show the time
       dateTimeCompact = dts.FormatTime("",
                                        dts.timeFormatNoSeconds,
                                        aDate.getHours(),
                                        aDate.getMinutes(),
                                        0);
     } else if (today - aDate < (24 * 60 * 60 * 1000)) {
       // After yesterday started, show yesterday
       dateTimeCompact = gBundle.GetStringFromName(gStr.yesterday);
     } else if (today - aDate < (6 * 24 * 60 * 60 * 1000)) {
       // After last week started, show day of week
       dateTimeCompact = typeof Intl === "undefined"
                         ? aDate.toLocaleFormat("%A")
-                        : aDate.toLocaleDateString(locale, { weekday: "long" });
+                        : aDate.toLocaleDateString(undefined, { weekday: "long" });
     } else {
       // Show month/day
       let month = typeof Intl === "undefined"
                   ? aDate.toLocaleFormat("%B")
-                  : aDate.toLocaleDateString(locale, { month: "long" });
+                  : aDate.toLocaleDateString(undefined, { month: "long" });
       let date = aDate.getDate();
       dateTimeCompact = gBundle.formatStringFromName(gStr.monthDate, [month, date], 2);
     }
 
     let dateTimeFull = dts.FormatDateTime("",
                                           dts.dateFormatLong,
                                           dts.timeFormatNoSeconds,
                                           aDate.getFullYear(),
--- a/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
+++ b/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
@@ -73,44 +73,37 @@ function testAllGetReadableDates() {
   const today_11_30     = new Date(2000, 11, 31, 11, 30, 15);
   const today_12_30     = new Date(2000, 11, 31, 12, 30, 15);
   const yesterday_11_30 = new Date(2000, 11, 30, 11, 30, 15);
   const yesterday_12_30 = new Date(2000, 11, 30, 12, 30, 15);
   const twodaysago      = new Date(2000, 11, 29, 11, 30, 15);
   const sixdaysago      = new Date(2000, 11, 25, 11, 30, 15);
   const sevendaysago    = new Date(2000, 11, 24, 11, 30, 15);
 
-  // TODO: Remove Intl fallback when no longer needed (bug 1344543).
-  const locale = typeof Intl === "undefined"
-                 ? undefined
-                 : Components.classes["@mozilla.org/chrome/chrome-registry;1"]
-                                     .getService(Components.interfaces.nsIXULChromeRegistry)
-                                     .getSelectedLocale("global", true);
-
   let dts = Components.classes["@mozilla.org/intl/scriptabledateformat;1"].
             getService(Components.interfaces.nsIScriptableDateFormat);
 
   testGetReadableDates(today_11_30, dts.FormatTime("", dts.timeFormatNoSeconds,
                                                    11, 30, 0));
   testGetReadableDates(today_12_30, dts.FormatTime("", dts.timeFormatNoSeconds,
                                                    12, 30, 0));
   testGetReadableDates(yesterday_11_30, "Yesterday");
   testGetReadableDates(yesterday_12_30, "Yesterday");
   testGetReadableDates(twodaysago,
                        typeof Intl === "undefined"
                        ? twodaysago.toLocaleFormat("%A")
-                       : twodaysago.toLocaleDateString(locale, { weekday: "long" }));
+                       : twodaysago.toLocaleDateString(undefined, { weekday: "long" }));
   testGetReadableDates(sixdaysago,
                        typeof Intl === "undefined"
                        ? sixdaysago.toLocaleFormat("%A")
-                       : sixdaysago.toLocaleDateString(locale, { weekday: "long" }));
+                       : sixdaysago.toLocaleDateString(undefined, { weekday: "long" }));
   testGetReadableDates(sevendaysago,
                        (typeof Intl === "undefined"
                         ? sevendaysago.toLocaleFormat("%B")
-                        : sevendaysago.toLocaleDateString(locale, { month: "long" })) + " " +
+                        : sevendaysago.toLocaleDateString(undefined, { month: "long" })) + " " +
                        sevendaysago.getDate().toString().padStart(2, "0"));
 
   let [, dateTimeFull] = DownloadUtils.getReadableDates(today_11_30);
   do_check_eq(dateTimeFull, dts.FormatDateTime("", dts.dateFormatLong,
                                                    dts.timeFormatNoSeconds,
                                                    2000, 12, 31, 11, 30, 0));
 }
 
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -1621,21 +1621,18 @@ function openOptionsInTab(optionsURL) {
   if ("switchToTabHavingURI" in mainWindow) {
     mainWindow.switchToTabHavingURI(optionsURL, true);
     return true;
   }
   return false;
 }
 
 function formatDate(aDate) {
-  const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
-                 .getService(Ci.nsIXULChromeRegistry)
-                 .getSelectedLocale("global", true);
   const dtOptions = { year: "numeric", month: "long", day: "numeric" };
-  return aDate.toLocaleDateString(locale, dtOptions);
+  return aDate.toLocaleDateString(undefined, dtOptions);
 }
 
 
 function hasPermission(aAddon, aPerm) {
   var perm = AddonManager["PERM_CAN_" + aPerm.toUpperCase()];
   return !!(aAddon.permissions & perm);
 }
 
--- a/toolkit/mozapps/extensions/content/extensions.xml
+++ b/toolkit/mozapps/extensions/content/extensions.xml
@@ -1186,21 +1186,18 @@
                                           this.mManualUpdate.releaseNotesURI :
                                           this.mAddon.releaseNotesURI);
         ]]></body>
       </method>
 
       <method name="_updateDates">
         <body><![CDATA[
           function formatDate(aDate) {
-            const locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
-                           .getService(Components.interfaces.nsIXULChromeRegistry)
-                           .getSelectedLocale("global", true);
             const dtOptions = { year: "numeric", month: "long", day: "numeric" };
-            return aDate.toLocaleDateString(locale, dtOptions);
+            return aDate.toLocaleDateString(undefined, dtOptions);
           }
 
           if (this.mAddon.updateDate)
             this._dateUpdated.value = formatDate(this.mAddon.updateDate);
           else
             this._dateUpdated.value = this._dateUpdated.getAttribute("unknown");
         ]]></body>
       </method>
--- a/toolkit/mozapps/extensions/test/browser/browser_experiments.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_experiments.js
@@ -91,18 +91,17 @@ add_task(function* initializeState() {
     }
     if (gExperiments) {
       let tmp = {};
       Cu.import("resource:///modules/experiments/Experiments.jsm", tmp);
       gExperiments._policy = new tmp.Experiments.Policy();
     }
   });
 
-  let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry);
-  gIsEnUsLocale = chrome.getSelectedLocale("global") == "en-US";
+  gIsEnUsLocale = Services.locale.getAppLocaleAsLangTag() == "en-US";
 
   // The Experiments Manager will interfere with us by preventing installs
   // of experiments it doesn't know about. We remove it from the equation
   // because here we are only concerned with core Addon Manager operation,
   // not the superset Experiments Manager has imposed.
   if ("@mozilla.org/browser/experiments-service;1" in Components.classes) {
     let tmp = {};
     Cu.import("resource:///modules/experiments/Experiments.jsm", tmp);
--- a/toolkit/mozapps/extensions/test/browser/head.js
+++ b/toolkit/mozapps/extensions/test/browser/head.js
@@ -494,21 +494,18 @@ function wait_for_window_open(aCallback)
 function get_string(aName, ...aArgs) {
   var bundle = Services.strings.createBundle("chrome://mozapps/locale/extensions/extensions.properties");
   if (aArgs.length == 0)
     return bundle.GetStringFromName(aName);
   return bundle.formatStringFromName(aName, aArgs, aArgs.length);
 }
 
 function formatDate(aDate) {
-  const locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
-                 .getService(Ci.nsIXULChromeRegistry)
-                 .getSelectedLocale("global", true);
   const dtOptions = { year: "numeric", month: "long", day: "numeric" };
-  return aDate.toLocaleDateString(locale, dtOptions);
+  return aDate.toLocaleDateString(undefined, dtOptions);
 }
 
 function is_hidden(aElement) {
   var style = aElement.ownerGlobal.getComputedStyle(aElement);
   if (style.display == "none")
     return true;
   if (style.visibility != "visible")
     return true;
--- a/toolkit/mozapps/update/content/history.js
+++ b/toolkit/mozapps/update/content/history.js
@@ -54,17 +54,14 @@ var gUpdateHistory = {
   /**
    * Formats a date into human readable form
    * @param   seconds
    *          A date in seconds since 1970 epoch
    * @returns A human readable date string
    */
   _formatDate(seconds) {
     var date = new Date(seconds);
-    const locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
-                   .getService(Components.interfaces.nsIXULChromeRegistry)
-                   .getSelectedLocale("global", true);
     const dtOptions = { year: "numeric", month: "long", day: "numeric",
                         hour: "numeric", minute: "numeric", second: "numeric" };
-    return date.toLocaleString(locale, dtOptions);
+    return date.toLocaleString(undefined, dtOptions);
   }
 };
 
--- a/uriloader/exthandler/nsHandlerService.js
+++ b/uriloader/exthandler/nsHandlerService.js
@@ -145,20 +145,19 @@ HandlerService.prototype = {
     } catch (ex) {
       // if injecting the defaults failed, set the version back to the
       // previous value
       this._datastoreDefaultHandlersVersion = defaultHandlersVersion;
     }
   },
 
   get _currentLocale() {
-    var chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].
-                         getService(Ci.nsIXULChromeRegistry);
-    var currentLocale = chromeRegistry.getSelectedLocale("global");
-    return currentLocale;
+    const locSvc = Cc["@mozilla.org/intl/localeservice;1"].
+                   getService(Ci.mozILocaleService);
+    return locSvc.getAppLocaleAsLangTag();
   }, 
 
   _destroy: function HS__destroy() {
     this._observerSvc.removeObserver(this, "profile-before-change");
     this._observerSvc.removeObserver(this, "xpcom-shutdown");
     this._observerSvc.removeObserver(this, "profile-do-change");
     this._observerSvc.removeObserver(this, "handlersvc-rdf-replace");