Bug 1493711 - Pref off downloading langpacks outside of release r=jaws a=jcristau
authorMark Striemer <mstriemer@mozilla.com>
Thu, 18 Oct 2018 14:36:39 +0000
changeset 501106 8034ed187c948ad0cfea0bca8d840f5fa3c3a980
parent 501105 7a1bcf3d6977e2944c6fd0c80b713e0add581848
child 501107 24ac9d53d202349388e7d35b5bf1934aa76fdc72
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws, jcristau
bugs1493711
milestone64.0
Bug 1493711 - Pref off downloading langpacks outside of release r=jaws a=jcristau Differential Revision: https://phabricator.services.mozilla.com/D8909
browser/app/profile/firefox.js
browser/components/preferences/browserLanguages.js
browser/components/preferences/in-content/main.js
browser/components/preferences/in-content/tests/browser_browser_languages_subdialog.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1754,16 +1754,22 @@ pref("app.normandy.shieldLearnMoreUrl", 
 #ifdef MOZ_DATA_REPORTING
 pref("app.shield.optoutstudies.enabled", true);
 #else
 pref("app.shield.optoutstudies.enabled", false);
 #endif
 
 // Multi-lingual preferences
 pref("intl.multilingual.enabled", false);
+// AMO only serves language packs for release versions, so this feature only works on release.
+#ifdef RELEASE
+pref("intl.multilingual.downloadEnabled", true);
+#else
+pref("intl.multilingual.downloadEnabled", false);
+#endif
 
 // Simulate conditions that will happen when the browser
 // is running with Fission enabled. This is meant to assist
 // development and testing of Fission.
 // The current simulated conditions are:
 // - Don't propagate events from subframes to JS child actors
 pref("browser.fission.simulate", false);
 
--- a/browser/components/preferences/browserLanguages.js
+++ b/browser/components/preferences/browserLanguages.js
@@ -288,16 +288,21 @@ function compareItems(a, b) {
   return -1;
 }
 
 var gBrowserLanguagesDialog = {
   _availableLocales: null,
   _requestedLocales: null,
   requestedLocales: null,
 
+  get downloadEnabled() {
+    // Downloading langpacks isn't always supported, check the pref.
+    return Services.prefs.getBoolPref("intl.multilingual.downloadEnabled");
+  },
+
   beforeAccept() {
     this.requestedLocales = this.getRequestedLocales();
     return true;
   },
 
   async onLoad() {
     // Maintain the previously requested locales even if we cancel out.
     let {requesting, search} = window.arguments[0] || {};
@@ -347,16 +352,20 @@ var gBrowserLanguagesDialog = {
     if (search) {
       return this.loadLocalesFromAMO();
     }
 
     return undefined;
   },
 
   async loadLocalesFromAMO() {
+    if (!this.downloadEnabled) {
+      return;
+    }
+
     // Disable the dropdown while we hit the network.
     this._availableLocales.disableWithMessageId("browser-languages-searching");
 
     // Fetch the available langpacks from AMO.
     let availableLangpacks;
     try {
       availableLangpacks = await AddonRepository.getAvailableLangpacks();
     } catch (e) {
@@ -399,20 +408,22 @@ var gBrowserLanguagesDialog = {
   async loadLocalesFromInstalled(available) {
     let items;
     if (available.length > 0) {
       items = getLocaleDisplayInfo(available);
       items.push(await this.createInstalledLabel());
     } else {
       items = [];
     }
-    items.push({
-      label: await document.l10n.formatValue("browser-languages-search"),
-      value: "search",
-    });
+    if (this.downloadEnabled) {
+      items.push({
+        label: await document.l10n.formatValue("browser-languages-search"),
+        value: "search",
+      });
+    }
     this._availableLocales.setItems(items);
   },
 
   async availableLanguageSelected(item) {
     if (Services.locale.availableLocales.includes(item.value)) {
       this.requestLocalLanguage(item);
     } else if (this.availableLangpacks.has(item.value)) {
       await this.requestRemoteLanguage(item);
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -750,25 +750,28 @@ var gMainPane = {
     let fragment = document.createDocumentFragment();
     for (let {code, name} of locales) {
       let menuitem = document.createXULElement("menuitem");
       menuitem.setAttribute("value", code);
       menuitem.setAttribute("label", name);
       fragment.appendChild(menuitem);
     }
 
-    // Add an option to search for more languages.
-    let menuitem = document.createXULElement("menuitem");
-    menuitem.id = "defaultBrowserLanguageSearch";
-    menuitem.setAttribute(
-      "label", await document.l10n.formatValue("browser-languages-search"));
-    menuitem.addEventListener("command", () => {
-      gMainPane.showBrowserLanguages({search: true});
-    });
-    fragment.appendChild(menuitem);
+    // Add an option to search for more languages if downloading is supported.
+    if (Services.prefs.getBoolPref("intl.multilingual.downloadEnabled")) {
+      let menuitem = document.createXULElement("menuitem");
+      menuitem.id = "defaultBrowserLanguageSearch";
+      menuitem.setAttribute(
+        "label", await document.l10n.formatValue("browser-languages-search"));
+      menuitem.setAttribute("value", "search");
+      menuitem.addEventListener("command", () => {
+        gMainPane.showBrowserLanguages({search: true});
+      });
+      fragment.appendChild(menuitem);
+    }
 
     let menulist = document.getElementById("defaultBrowserLanguage");
     let menupopup = menulist.querySelector("menupopup");
     menupopup.textContent = "";
     menupopup.appendChild(fragment);
     menulist.value = requesting;
 
     document.getElementById("browserLanguagesBox").hidden = false;
--- a/browser/components/preferences/in-content/tests/browser_browser_languages_subdialog.js
+++ b/browser/components/preferences/in-content/tests/browser_browser_languages_subdialog.js
@@ -158,16 +158,17 @@ async function openDialog(doc, search = 
     requested: dialogDoc.getElementById("requestedLocales"),
   };
 }
 
 add_task(async function testReorderingBrowserLanguages() {
   await SpecialPowers.pushPrefEnv({
     set: [
       ["intl.multilingual.enabled", true],
+      ["intl.multilingual.downloadEnabled", true],
       ["intl.locale.requested", "pl,en-US"],
     ],
   });
 
   await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
 
   let doc = gBrowser.contentDocument;
   let messageBar = doc.getElementById("confirmBrowserLanguage");
@@ -214,16 +215,17 @@ add_task(async function testReorderingBr
 
   BrowserTestUtils.removeTab(gBrowser.selectedTab);
 });
 
 add_task(async function testAddAndRemoveRequestedLanguages() {
   await SpecialPowers.pushPrefEnv({
     set: [
       ["intl.multilingual.enabled", true],
+      ["intl.multilingual.downloadEnabled", true],
       ["intl.locale.requested", "en-US"],
       ["extensions.langpacks.signatures.required", false],
     ],
   });
 
   let langpacks = await createTestLangpacks();
   let addons = await Promise.all(langpacks.map(async ([locale, file]) => {
     let install = await AddonTestUtils.promiseInstallFile(file);
@@ -287,16 +289,17 @@ add_task(async function testInstallFromA
   let langpacksFile = await createLanguageToolsFile();
   let langpacksUrl = Services.io.newFileURI(langpacksFile).spec;
   let dictionaryBrowseFile = await createDictionaryBrowseResults();
   let browseApiEndpoint = Services.io.newFileURI(dictionaryBrowseFile).spec;
 
   await SpecialPowers.pushPrefEnv({
     set: [
       ["intl.multilingual.enabled", true],
+      ["intl.multilingual.downloadEnabled", true],
       ["intl.locale.requested", "en-US"],
       ["extensions.getAddons.langpacks.url", langpacksUrl],
       ["extensions.langpacks.signatures.required", false],
       ["extensions.getAddons.get.url", browseApiEndpoint],
     ],
   });
 
   await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
@@ -355,8 +358,51 @@ add_task(async function testInstallFromA
 
   // Uninstall the langpack and dictionary.
   let installs = await AddonManager.getAddonsByTypes(["locale", "dictionary"]);
   is(installs.length, 2, "There is one langpack and one dictionary installed");
   await Promise.all(installs.map(item => item.uninstall()));
 
   BrowserTestUtils.removeTab(gBrowser.selectedTab);
 });
+
+let hasSearchOption = popup => Array.from(popup.children).some(el => el.value == "search");
+
+add_task(async function testDownloadEnabled() {
+  await SpecialPowers.pushPrefEnv({
+    set: [
+      ["intl.multilingual.enabled", true],
+      ["intl.multilingual.downloadEnabled", true],
+    ],
+  });
+
+  await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
+  let doc = gBrowser.contentDocument;
+
+  let defaultMenulist = doc.getElementById("defaultBrowserLanguage");
+  ok(hasSearchOption(defaultMenulist.firstChild), "There's a search option in the General pane");
+
+  let { available } = await openDialog(doc, false);
+  ok(hasSearchOption(available.firstChild), "There's a search option in the dialog");
+
+  BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
+
+
+add_task(async function testDownloadDisabled() {
+  await SpecialPowers.pushPrefEnv({
+    set: [
+      ["intl.multilingual.enabled", true],
+      ["intl.multilingual.downloadEnabled", false],
+    ],
+  });
+
+  await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
+  let doc = gBrowser.contentDocument;
+
+  let defaultMenulist = doc.getElementById("defaultBrowserLanguage");
+  ok(!hasSearchOption(defaultMenulist.firstChild), "There's no search option in the General pane");
+
+  let { available } = await openDialog(doc, false);
+  ok(!hasSearchOption(available.firstChild), "There's no search option in the dialog");
+
+  BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});