bug 848297, allow overrides of locales for packages, r=bsmedberg
authorAxel Hecht <axel@pike.org>
Fri, 26 Apr 2013 17:11:47 +0200
changeset 130087 21cd4d9e679b
parent 130086 9df37c60263f
child 130088 2c1cdf681fff
push id24596
push userryanvm@gmail.com
push date2013-04-27 01:20 +0000
treeherdermozilla-central@0e45f1b9521f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs848297
milestone23.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 848297, allow overrides of locales for packages, r=bsmedberg
chrome/src/nsChromeRegistryChrome.cpp
chrome/src/nsChromeRegistryChrome.h
chrome/test/unit/data/test_bug848297.manifest
chrome/test/unit/test_bug848297.js
chrome/test/unit/xpcshell.ini
--- a/chrome/src/nsChromeRegistryChrome.cpp
+++ b/chrome/src/nsChromeRegistryChrome.cpp
@@ -31,28 +31,30 @@
 #include "mozilla/LookAndFeel.h"
 
 #include "nsICommandLine.h"
 #include "nsILocaleService.h"
 #include "nsIFile.h"
 #include "nsIObserverService.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
+#include "mozilla/Preferences.h"
 #include "nsIResProtocolHandler.h"
 #include "nsIScriptError.h"
 #include "nsIVersionComparator.h"
 #include "nsIXPConnect.h"
 #include "nsIXULAppInfo.h"
 #include "nsIXULRuntime.h"
 
 #define UILOCALE_CMD_LINE_ARG "UILocale"
 
 #define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
 #define SELECTED_LOCALE_PREF "general.useragent.locale"
 #define SELECTED_SKIN_PREF   "general.skins.selectedSkin"
+#define PACKAGE_OVERRIDE_BRANCH "chrome.override_package."
 
 using namespace mozilla;
 
 static PLDHashOperator
 RemoveAll(PLDHashTable *table, PLDHashEntryHdr *entry, uint32_t number, void *arg)
 {
   return (PLDHashOperator) (PL_DHASH_NEXT | PL_DHASH_REMOVE);
 }
@@ -191,30 +193,35 @@ nsChromeRegistryChrome::CheckForOSAccess
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsChromeRegistryChrome::GetLocalesForPackage(const nsACString& aPackage,
                                        nsIUTF8StringEnumerator* *aResult)
 {
+  nsCString realpackage;
+  nsresult rv = OverrideLocalePackage(aPackage, realpackage);
+  if (NS_FAILED(rv))
+    return rv;
+
   nsTArray<nsCString> *a = new nsTArray<nsCString>;
   if (!a)
     return NS_ERROR_OUT_OF_MEMORY;
 
   PackageEntry* entry =
       static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
-                                                      & aPackage,
+                                                      & realpackage,
                                                       PL_DHASH_LOOKUP));
 
   if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
     entry->locales.EnumerateToArray(a);
   }
 
-  nsresult rv = NS_NewAdoptingUTF8StringEnumerator(aResult, a);
+  rv = NS_NewAdoptingUTF8StringEnumerator(aResult, a);
   if (NS_FAILED(rv))
     delete a;
 
   return rv;
 }
 
 static nsresult
 getUILangCountry(nsACString& aUILang)
@@ -262,32 +269,51 @@ nsChromeRegistryChrome::IsLocaleRTL(cons
   *aResult = dir.EqualsLiteral("rtl");
   return NS_OK;
 }
 
 nsresult
 nsChromeRegistryChrome::GetSelectedLocale(const nsACString& aPackage,
                                           nsACString& aLocale)
 {
+  nsCString realpackage;
+  nsresult rv = OverrideLocalePackage(aPackage, realpackage);
+  if (NS_FAILED(rv))
+    return rv;
   PackageEntry* entry =
       static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
-                                                      & aPackage,
+                                                      & realpackage,
                                                       PL_DHASH_LOOKUP));
 
   if (PL_DHASH_ENTRY_IS_FREE(entry))
     return NS_ERROR_FAILURE;
 
   aLocale = entry->locales.GetSelected(mSelectedLocale, nsProviderArray::LOCALE);
   if (aLocale.IsEmpty())
     return NS_ERROR_FAILURE;
 
   return NS_OK;
 }
 
 nsresult
+nsChromeRegistryChrome::OverrideLocalePackage(const nsACString& aPackage,
+                                              nsACString& aOverride)
+{
+  const nsACString& pref = NS_LITERAL_CSTRING(PACKAGE_OVERRIDE_BRANCH) + aPackage;
+  nsAdoptingCString override = mozilla::Preferences::GetCString(PromiseFlatCString(pref).get());
+  if (override) {
+    aOverride = override;
+  }
+  else {
+    aOverride = aPackage;
+  }
+  return NS_OK;
+}
+
+nsresult
 nsChromeRegistryChrome::SelectLocaleFromPref(nsIPrefBranch* prefs)
 {
   nsresult rv;
   bool matchOSLocale = false;
   rv = prefs->GetBoolPref(MATCH_OS_LOCALE_PREF, &matchOSLocale);
 
   if (NS_SUCCEEDED(rv) && matchOSLocale) {
     // compute lang and region code only when needed!
--- a/chrome/src/nsChromeRegistryChrome.h
+++ b/chrome/src/nsChromeRegistryChrome.h
@@ -45,16 +45,18 @@ class nsChromeRegistryChrome : public ns
   
   void SendRegisteredChrome(mozilla::dom::PContentParent* aChild);
 
  private:
   static PLDHashOperator CollectPackages(PLDHashTable *table,
                                          PLDHashEntryHdr *entry,
                                          uint32_t number, void *arg);
 
+  nsresult OverrideLocalePackage(const nsACString& aPackage,
+                                 nsACString& aOverride);
   nsresult SelectLocaleFromPref(nsIPrefBranch* prefs);
   nsresult UpdateSelectedLocale() MOZ_OVERRIDE;
   nsIURI* GetBaseURIFromPackage(const nsCString& aPackage,
                                  const nsCString& aProvider,
                                  const nsCString& aPath) MOZ_OVERRIDE;
   nsresult GetFlagsFromPackage(const nsCString& aPackage,
                                uint32_t* aFlags) MOZ_OVERRIDE;
 
new file mode 100644
--- /dev/null
+++ b/chrome/test/unit/data/test_bug848297.manifest
@@ -0,0 +1,4 @@
+locale basepack en-US jar:en-US.jar!/locale/en-US/global/
+locale basepack fr jar:en-US.jar!/locale/en-US/global/
+locale overpack en-US jar:en-US.jar!/locale/en-US/global/
+locale overpack de jar:en-US.jar!/locale/en-US/global/
new file mode 100644
--- /dev/null
+++ b/chrome/test/unit/test_bug848297.js
@@ -0,0 +1,48 @@
+/* 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/.
+ */
+
+var MANIFESTS = [
+  do_get_file("data/test_bug848297.manifest")
+];
+
+// Stub in the locale service so we can control what gets returned as the OS locale setting
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+registerManifests(MANIFESTS);
+
+var chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"]
+                .getService(Ci.nsIXULChromeRegistry)
+                .QueryInterface(Ci.nsIToolkitChromeRegistry);
+chromeReg.checkForNewChrome();
+
+var prefService = Cc["@mozilla.org/preferences-service;1"]
+                  .getService(Ci.nsIPrefService)
+                  .QueryInterface(Ci.nsIPrefBranch);
+
+function enum_to_array(strings) {
+  let rv = [];
+  while (strings.hasMore()) {
+    rv.push(strings.getNext());
+  }
+  rv.sort();
+  return rv;
+}
+
+function run_test() {
+
+  // without override
+  prefService.setCharPref("general.useragent.locale", "de");
+  do_check_eq(chromeReg.getSelectedLocale("basepack"), "en-US");
+  do_check_eq(chromeReg.getSelectedLocale("overpack"), "de");
+  do_check_matches(enum_to_array(chromeReg.getLocalesForPackage("basepack")),
+                   ['en-US', 'fr']);
+
+  // with override
+  prefService.setCharPref("chrome.override_package.basepack", "overpack");
+  do_check_eq(chromeReg.getSelectedLocale("basepack"), "de");
+  do_check_matches(enum_to_array(chromeReg.getLocalesForPackage("basepack")),
+                   ['de', 'en-US']);
+
+}
--- a/chrome/test/unit/xpcshell.ini
+++ b/chrome/test/unit/xpcshell.ini
@@ -6,12 +6,13 @@ tail =
 [test_bug292789.js]
 [test_bug380398.js]
 [test_bug397073.js]
 [test_bug399707.js]
 [test_bug401153.js]
 [test_bug415367.js]
 [test_bug519468.js]
 [test_bug564667.js]
+[test_bug848297.js]
 [test_crlf.js]
 [test_data_protocol_registration.js]
 [test_no_remote_registration.js]
 [test_resolve_uris.js]