Bug 1479008 - Install related dictionaries after a langpack is installed r=leplatrem,aswan
authorMark Striemer <mstriemer@mozilla.com>
Thu, 18 Oct 2018 16:48:12 +0000
changeset 500416 6b1ecbbb842712c0a40d78dd39d5aea0ea615d15
parent 500415 8fc40677cc0eff1eb03a17169ea6997666136b75
child 500432 1635530c393a0f80512a3cf695fe968eb53562f2
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)
reviewersleplatrem, aswan
bugs1479008
milestone64.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 1479008 - Install related dictionaries after a langpack is installed r=leplatrem,aswan Differential Revision: https://phabricator.services.mozilla.com/D8442
browser/components/preferences/browserLanguages.js
browser/components/preferences/in-content/tests/addons/pl-dictionary.xpi
browser/components/preferences/in-content/tests/browser.ini
browser/components/preferences/in-content/tests/browser_browser_languages_subdialog.js
services/settings/dumps/main/language-dictionaries.json
services/settings/dumps/main/moz.build
--- a/browser/components/preferences/browserLanguages.js
+++ b/browser/components/preferences/browserLanguages.js
@@ -5,16 +5,34 @@
 /* import-globals-from ../../../toolkit/content/preferencesBindings.js */
 
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 ChromeUtils.defineModuleGetter(this, "AddonManager",
                                "resource://gre/modules/AddonManager.jsm");
 ChromeUtils.defineModuleGetter(this, "AddonRepository",
                                "resource://gre/modules/addons/AddonRepository.jsm");
+ChromeUtils.defineModuleGetter(this, "RemoteSettings",
+                               "resource://services-settings/remote-settings.js");
+
+async function installFromUrl(url, hash) {
+  let install = await AddonManager.getInstallForURL(
+    url, "application/x-xpinstall", hash);
+  return install.install();
+}
+
+async function dictionaryIdsForLocale(locale) {
+  let entries = await RemoteSettings("language-dictionaries").get({
+    filters: {id: locale},
+  });
+  if (entries.length > 0) {
+    return entries[0].dictionaries;
+  }
+  return [];
+}
 
 class OrderedListBox {
   constructor({richlistbox, upButton, downButton, removeButton, onRemove}) {
     this.richlistbox = richlistbox;
     this.upButton = upButton;
     this.downButton = downButton;
     this.removeButton = removeButton;
     this.onRemove = onRemove;
@@ -389,47 +407,71 @@ var gBrowserLanguagesDialog = {
     items.push({
       label: await document.l10n.formatValue("browser-languages-search"),
       value: "search",
     });
     this._availableLocales.setItems(items);
   },
 
   async availableLanguageSelected(item) {
-    let available = new Set(Services.locale.availableLocales);
-
-    if (available.has(item.value)) {
-      this._requestedLocales.addItem(item);
-      if (available.size == this._requestedLocales.items.length) {
-        // Remove the installed label, they're all installed.
-        this._availableLocales.items.shift();
-        this._availableLocales.setItems(this._availableLocales.items);
-      }
+    if (Services.locale.availableLocales.includes(item.value)) {
+      this.requestLocalLanguage(item);
     } else if (this.availableLangpacks.has(item.value)) {
-      this._availableLocales.disableWithMessageId("browser-languages-downloading");
-
-      let {url, hash} = this.availableLangpacks.get(item.value);
-      let install = await AddonManager.getInstallForURL(
-        url, "application/x-xpinstall", hash);
-
-      try {
-        await install.install();
-      } catch (e) {
-        this.showError();
-        return;
-      }
-
-      item.installed = true;
-      this._requestedLocales.addItem(item);
-      this._availableLocales.enableWithMessageId("browser-languages-select-language");
+      await this.requestRemoteLanguage(item);
     } else {
       this.showError();
     }
   },
 
+  requestLocalLanguage(item, available) {
+    this._requestedLocales.addItem(item);
+    let requestedCount = this._requestedLocales.items.length;
+    let availableCount = Services.locale.availableLocales.length;
+    if (requestedCount == availableCount) {
+      // Remove the installed label, they're all installed.
+      this._availableLocales.items.shift();
+      this._availableLocales.setItems(this._availableLocales.items);
+    }
+  },
+
+  async requestRemoteLanguage(item) {
+    this._availableLocales.disableWithMessageId(
+      "browser-languages-downloading");
+
+    let {url, hash} = this.availableLangpacks.get(item.value);
+
+    try {
+      await installFromUrl(url, hash);
+    } catch (e) {
+      this.showError();
+      return;
+    }
+
+    item.installed = true;
+    this._requestedLocales.addItem(item);
+    this._availableLocales.enableWithMessageId(
+      "browser-languages-select-language");
+
+    // This is an async task that will install the recommended dictionaries for
+    // this locale. This will fail silently at least until a management UI is
+    // added in bug 1493705.
+    this.installDictionariesForLanguage(item.value);
+  },
+
+  async installDictionariesForLanguage(locale) {
+    try {
+      let ids = await dictionaryIdsForLocale(locale);
+      let addonInfos = await AddonRepository.getAddonsByIDs(ids);
+      await Promise.all(addonInfos.map(
+        info => installFromUrl(info.sourceURI.spec)));
+    } catch (e) {
+      Cu.reportError(e);
+    }
+  },
+
   showError() {
     document.querySelectorAll(".warning-message-separator")
       .forEach(separator => separator.classList.add("thin"));
     document.getElementById("warning-message").hidden = false;
     this._availableLocales.enableWithMessageId("browser-languages-select-language");
   },
 
   hideError() {
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3113d1fa5da0482256cef2fd3edf78ad2f6e7bc2
GIT binary patch
literal 963
zc$^FHW@Zs#U|`^25U%v`)pC+`E?{I}U}t7v;AW6v$jmD)NzBR7D@sWV4dG;9cKd%I
zx)g*fxEUB(z5-Q(HRn$9FK#jrIQqVhtLyoM56iW9j+Gtzc<1H9@1jj<T%40zR=xeQ
zTYRxg&gstD_umh_YpW^E$$H<cd3I^UuSADGqH~|Df8Bds+DZTKUc=nBj}Hqt_zD%S
z^0jBqN)mdg;k0Va1UpV<ca<+!=2tvF&Sre=PO9|Jldq-TFbXPirk%C4{hBF%>bj43
z*Y;)khnm;EIdkd#loRU~_HgGeSQp6L6z(G}{VI9Q$qLWgzg9juYRTPYEb9>IweWcS
znUAd{D_<YjGT*$z!$LW5%Z3XH7Mp~1Mc!Xo(HHq3%KHACD7W;^uWxo2Zwr#j71^@=
zgKyE4hPI31k;QwrcdVTot-<D|wQJ&~UCwVCK5g6aQ8T%+s8L?vlUdA0FFD&5H|B<0
zhM(_jGu1z^<K}z))C+gc?T^@~V7T(xiVltiDbqqU?h3UXl1TE1wCWc>`Tg#__L9R#
zZ<n6#XWV$gW0(6wix(%867p|d(D--x<x{JFv)_o%dHgSY`DFP3V5D&|fPgYE(pqfH
zLL-4}5EceTT1sYeNoIatVo_#lv3^00USb*~@{)iNmx392!LA_+p27YW7N(ZEMqD95
zkqU{K`KeWTMditr#RVnVxhb20v9&QhDdW|)XP@_{ecV%4SmEgD?;7P76z&`u91!B|
z>#{i1$7`XxlgFuL$1bmTySOGSFoFx=N)4bZ*%!XL%LHUI;cz984|ZiX(1qEUu1o|P
z$H*kdj4Q25fGq-Y8J0AHSSTr%6`FEUjf5D8D;$vx+zO<yhAJy0RPh*$>2+j-qnR)b
Z1_uNyBp@&hW@Q6uW(Gl^;3|-b3;>KuQZoPm
--- a/browser/components/preferences/in-content/tests/browser.ini
+++ b/browser/components/preferences/in-content/tests/browser.ini
@@ -1,15 +1,16 @@
 [DEFAULT]
 prefs =
   extensions.formautofill.available='on'
   extensions.formautofill.creditCards.available=true
 support-files =
   head.js
   privacypane_tests_perwindow.js
+  addons/pl-dictionary.xpi
   addons/set_homepage.xpi
   addons/set_newtab.xpi
 
 [browser_applications_selection.js]
 [browser_advanced_update.js]
 skip-if = !updater
 [browser_basic_rebuild_fonts_test.js]
 [browser_bug410900.js]
--- a/browser/components/preferences/in-content/tests/browser_browser_languages_subdialog.js
+++ b/browser/components/preferences/in-content/tests/browser_browser_languages_subdialog.js
@@ -1,17 +1,19 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm", this);
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
+
 AddonTestUtils.initMochitest(this);
 
 const BROWSER_LANGUAGES_URL = "chrome://browser/content/preferences/browserLanguages.xul";
+const DICTIONARY_ID_PL = "pl@dictionaries.addons.mozilla.org";
 
 function getManifestData(locale) {
   return {
     langpack_id: locale,
     name: `${locale} Language Pack`,
     description: `${locale} Language pack`,
     languages: {
       [locale]: {
@@ -74,16 +76,55 @@ async function createLanguageToolsFile()
   let files = {[filename]: {results}};
   let tempdir = AddonTestUtils.tempDir.clone();
   let dir = await AddonTestUtils.promiseWriteFilesToDir(tempdir.path, files);
   dir.append(filename);
 
   return dir;
 }
 
+async function createDictionaryBrowseResults() {
+  let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
+  let dictionaryPath = testDir + "/addons/pl-dictionary.xpi";
+  let filename = "dictionaries.json";
+  let response = {
+    page_size: 25,
+    page_count: 1,
+    count: 1,
+    results: [{
+      current_version: {
+        id: 1823648,
+        compatibility: {
+          firefox: {max: "9999", min: "4.0"},
+        },
+        files: [{
+          platform: "all",
+          url: dictionaryPath,
+        }],
+        version: "1.0.20160228",
+      },
+      default_locale: "pl",
+      description: "Polish spell-check",
+      guid: DICTIONARY_ID_PL,
+      name: "Polish Dictionary",
+      slug: "polish-spellchecker-dictionary",
+      status: "public",
+      summary: "Polish dictionary",
+      type: "dictionary",
+    }],
+  };
+
+  let files = {[filename]: response};
+  let dir = await AddonTestUtils.promiseWriteFilesToDir(
+    AddonTestUtils.tempDir.path, files);
+  dir.append(filename);
+
+  return dir;
+}
+
 function assertLocaleOrder(list, locales) {
   is(list.itemCount, locales.split(",").length,
      "The right number of locales are requested");
   is(Array.from(list.children).map(child => child.value).join(","),
      locales, "The requested locales are in order");
 }
 
 function assertAvailableLocales(list, locales) {
@@ -240,22 +281,26 @@ add_task(async function testAddAndRemove
 });
 
 add_task(async function testInstallFromAMO() {
   let langpacks = await AddonManager.getAddonsByTypes(["locale"]);
   is(langpacks.length, 0, "There are no langpacks installed");
 
   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.locale.requested", "en-US"],
       ["extensions.getAddons.langpacks.url", langpacksUrl],
       ["extensions.langpacks.signatures.required", false],
+      ["extensions.getAddons.get.url", browseApiEndpoint],
     ],
   });
 
   await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
 
   let doc = gBrowser.contentDocument;
   let messageBar = doc.getElementById("confirmBrowserLanguage");
   is(messageBar.hidden, true, "The message bar is hidden at first");
@@ -272,31 +317,46 @@ add_task(async function testInstallFromA
   }
 
   // The initial order is set by the pref.
   assertLocaleOrder(requested, "en-US");
   assertAvailableLocales(available, ["fr", "he", "pl"]);
   is(Services.locale.availableLocales.join(","),
      "en-US", "There is only one installed locale");
 
+  // Verify that there are no extra dictionaries.
+  let dicts = await AddonManager.getAddonsByTypes(["dictionary"]);
+  is(dicts.length, 0, "There are no installed dictionaries");
+
   // Add Polish, this will install the langpack.
   requestLocale("pl", available, dialogDoc);
 
   // Wait for the langpack to install and be added to the list.
   let requestedLocales = dialogDoc.getElementById("requestedLocales");
   await waitForMutation(
     requestedLocales,
     {childList: true},
     target => requestedLocales.itemCount == 2);
 
   // Verify the list is correct.
   assertLocaleOrder(requested, "pl,en-US");
   assertAvailableLocales(available, ["fr", "he"]);
   is(Services.locale.availableLocales.sort().join(","),
      "en-US,pl", "Polish is now installed");
 
-  // Uninstall the langpack.
-  langpacks = await AddonManager.getAddonsByTypes(["locale"]);
-  is(langpacks.length, 1, "There is one langpacks installed");
-  await Promise.all(langpacks.map(pack => pack.uninstall()));
+  await BrowserTestUtils.waitForCondition(async () => {
+    let newDicts = await AddonManager.getAddonsByTypes(["dictionary"]);
+    let done = newDicts.length != 0;
+
+    if (done) {
+      is(newDicts[0].id, DICTIONARY_ID_PL, "The polish dictionary was installed");
+    }
+
+    return done;
+  });
+
+  // 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);
 });
new file mode 100644
--- /dev/null
+++ b/services/settings/dumps/main/language-dictionaries.json
@@ -0,0 +1,1 @@
+{"data":[{"schema":1539698850177,"dictionaries":["xh-ZA@dictionaries.addons.mozilla.org"],"id":"xh","last_modified":1539698851548},{"schema":1539698850177,"dictionaries":["dictionary@vi.mozdev.org"],"id":"vi","last_modified":1539698851493},{"schema":1539698850177,"dictionaries":["uz@dellalibera.sf.net"],"id":"uz","last_modified":1539698851437},{"schema":1539698847383,"dictionaries":["ur@dictionaries.addons.mozilla.org"],"id":"ur","last_modified":1539698850171},{"schema":1539698847383,"dictionaries":["uk-ua@dictionaries.addons.mozilla.org"],"id":"uk","last_modified":1539698850116},{"schema":1539698847383,"dictionaries":["tr-fix@dictionaries.addons.mozilla.org"],"id":"tr","last_modified":1539698850060},{"schema":1539698847383,"dictionaries":["indlinux-telugu@lists.sourceforge.net"],"id":"te","last_modified":1539698850002},{"schema":1539698847383,"dictionaries":["mugunth@thamizha.com"],"id":"ta","last_modified":1539698849944},{"schema":1539698847383,"dictionaries":["swedish@dictionaries.addons.mozilla.org"],"id":"sv-SE","last_modified":1539698849888},{"schema":1539698847383,"dictionaries":["sr-RS@dictionaries.addons.mozilla.org"],"id":"sr","last_modified":1539698849834},{"schema":1539698847383,"dictionaries":["sq-AL@dictionaries.addons.mozilla.org"],"id":"sq","last_modified":1539698849779},{"schema":1539698847383,"dictionaries":["son-ML@dictionaries.addons.mozilla.org"],"id":"son","last_modified":1539698849726},{"schema":1539698847383,"dictionaries":["sl@dictionaries.addons.mozilla.org"],"id":"sl","last_modified":1539698849672},{"schema":1539698847383,"dictionaries":["sk@dictionaries.addons.mozilla.org"],"id":"sk","last_modified":1539698849619},{"schema":1539698847383,"dictionaries":["ru@dictionaries.addons.mozilla.org"],"id":"ru","last_modified":1539698849564},{"schema":1539698847383,"dictionaries":["ro-RO@www.archeus.ro"],"id":"ro","last_modified":1539698849510},{"schema":1539698847383,"dictionaries":["pt-PT@dictionaries.addons.mozilla.org"],"id":"pt-PT","last_modified":1539698849457},{"schema":1539698847383,"dictionaries":["pt-BR@dellalibera.sf.net"],"id":"pt-BR","last_modified":1539698849404},{"schema":1539698847383,"dictionaries":["pl@dictionaries.addons.mozilla.org"],"id":"pl","last_modified":1539698849351},{"schema":1539698847383,"dictionaries":["pa_IN@dellalibera.sf.net"],"id":"pa-IN","last_modified":1539698849297},{"schema":1539698847383,"dictionaries":["or_IN@dellalibera.sf.net"],"id":"or","last_modified":1539698849241},{"schema":1539698847383,"dictionaries":["nn-NO@dictionaries.addons.mozilla.org"],"id":"nn-NO","last_modified":1539698849187},{"schema":1539698847383,"dictionaries":["nl-NL@dictionaries.addons.mozilla.org"],"id":"nl","last_modified":1539698849133},{"schema":1539698847383,"dictionaries":["ne-NP@dictionaries.addons.mozilla.org"],"id":"ne-NP","last_modified":1539698849077},{"schema":1539698847383,"dictionaries":["nb-NO@dictionaries.addons.mozilla.org"],"id":"nb-NO","last_modified":1539698849022},{"schema":1539698847383,"dictionaries":["MyEja@xanda.org"],"id":"ms","last_modified":1539698848966},{"schema":1539698847383,"dictionaries":["mr-IN@dictionaries.addons.mozilla.org"],"id":"mr","last_modified":1539698848910},{"schema":1539698847383,"dictionaries":["mk-MK@dictionaries.addons.mozilla.org"],"id":"mk","last_modified":1539698848856},{"schema":1539698844602,"dictionaries":["lv-LV@dictionaries.addons.mozilla.org"],"id":"lv","last_modified":1539698847376},{"schema":1539698844602,"dictionaries":["lt@dictionaries.addons.mozilla.org"],"id":"lt","last_modified":1539698847321},{"schema":1539698844602,"dictionaries":["lo@dictionaries.addons.mozilla.org"],"id":"lo","last_modified":1539698847259},{"schema":1539698844602,"dictionaries":["ko-KR@dictionaries.addons.mozilla.org"],"id":"ko","last_modified":1539698847204},{"schema":1539698844602,"dictionaries":["kn@dictionaries.addons.mozilla.org"],"id":"kn","last_modified":1539698847151},{"schema":1539698844602,"dictionaries":["ka-GE@dictionaries.addons.mozilla.org"],"id":"ka","last_modified":1539698847096},{"schema":1539698844602,"dictionaries":["it-IT@dictionaries.addons.mozilla.org"],"id":"it","last_modified":1539698847039},{"schema":1539698844602,"dictionaries":["is@dictionaries.addons.mozilla.org"],"id":"is","last_modified":1539698846985},{"schema":1539698844602,"dictionaries":["id@ewesewes.net"],"id":"id","last_modified":1539698846932},{"schema":1539698844602,"dictionaries":["ia-xx@dictionaries.addons.mozilla.org"],"id":"ia","last_modified":1539698846878},{"schema":1539698844602,"dictionaries":["am@dictionaries.addons.mozilla.org"],"id":"hy-AM","last_modified":1539698846821},{"schema":1539698844602,"dictionaries":["hu@dictionaries.addons.mozilla.org"],"id":"hu","last_modified":1539698846767},{"schema":1539698844602,"dictionaries":["hsb@dictionaries.addons.mozilla.org"],"id":"hsb","last_modified":1539698846709},{"schema":1539698844602,"dictionaries":["hr-HR-2@dictionaries.addons.mozilla.org"],"id":"hr","last_modified":1539698846655},{"schema":1539698844602,"dictionaries":["hi-IN@dellalibera.sf.net"],"id":"hi-IN","last_modified":1539698846599},{"schema":1539698844602,"dictionaries":["he@dictionaries.addons.mozilla.org"],"id":"he","last_modified":1539698846544},{"schema":1539698844602,"dictionaries":["gu-IN@dellalibera.sf.net"],"id":"gu-IN","last_modified":1539698846488},{"schema":1539698844602,"dictionaries":["gl-es@dictionaries.addons.mozilla.org"],"id":"gl","last_modified":1539698846434},{"schema":1539698844602,"dictionaries":["gd-GB@dictionaries.addons.mozilla.org"],"id":"gd","last_modified":1539698846381},{"schema":1539698844602,"dictionaries":["ga-IE@dictionaries.addons.mozilla.org"],"id":"ga-IE","last_modified":1539698846327},{"schema":1539698844602,"dictionaries":["fy@dictionaries.addons.mozilla.org"],"id":"fy-NL","last_modified":1539698846271},{"schema":1539698844602,"dictionaries":["fr-dicollecte@dictionaries.addons.mozilla.org"],"id":"fr","last_modified":1539698846217},{"schema":1539698844602,"dictionaries":["fa@dictionaries.addons.mozilla.org"],"id":"fa","last_modified":1539698846162},{"schema":1539698844602,"dictionaries":["eu@dictionaries.addons.mozilla.org"],"id":"eu","last_modified":1539698846108},{"schema":1539698844602,"dictionaries":["et-EE@dictionaries.addons.mozilla.org"],"id":"et","last_modified":1539698846053},{"schema":1537961639183,"dictionaries":["diccionario@mozilla-mexico.org"],"id":"es-MX","last_modified":1539698844595},{"schema":1537961639183,"dictionaries":["es-es@dictionaries.addons.mozilla.org"],"id":"es-ES","last_modified":1539698844540},{"schema":1537961639183,"dictionaries":["es_cl@dictionaries.addons.mozilla.org"],"id":"es-CL","last_modified":1539698844485},{"schema":1537961639183,"dictionaries":["es-AR@dictionaries.addons.mozilla.org"],"id":"es-AR","last_modified":1539698844432},{"schema":1537961639183,"dictionaries":["eo-EO@dictionaries.addons.mozilla.org"],"id":"eo","last_modified":1539698844376},{"schema":1537961639183,"dictionaries":["@unitedstatesenglishdictionary"],"id":"en-US","last_modified":1539698844315},{"schema":1537961639183,"dictionaries":["marcoagpinto@mail.telepac.pt"],"id":"en-GB","last_modified":1539698844263},{"schema":1537961639183,"dictionaries":["en-CA@dictionaries.addons.mozilla.org"],"id":"en-CA","last_modified":1539698844210},{"schema":1537961639183,"dictionaries":["el-GR@dictionaries.addons.mozilla.org"],"id":"el","last_modified":1539698844158},{"schema":1537961639183,"dictionaries":["dsb@dictionaries.addons.mozilla.org"],"id":"dsb","last_modified":1539698844105},{"schema":1537961639183,"dictionaries":["de-CH@dictionaries.addons.mozilla.org","de-DE@dictionaries.addons.mozilla.org","de-AT@dictionaries.addons.mozilla.org"],"id":"de","last_modified":1539698844047},{"schema":1537961639183,"dictionaries":["danish@dictionaries.addons.mozilla.org"],"id":"da","last_modified":1539698843991},{"schema":1537961639183,"dictionaries":["cy-GB-1@dictionaries.addons.mozilla.org"],"id":"cy","last_modified":1539698843935},{"schema":1537961639183,"dictionaries":["cs@dictionaries.addons.mozilla.org"],"id":"cs","last_modified":1539698843864},{"schema":1537961639183,"dictionaries":["ca@dictionaries.addons.mozilla.org"],"id":"ca","last_modified":1539698843809},{"schema":1537961639183,"dictionaries":["br@dictionaries.addons.mozilla.org"],"id":"br","last_modified":1539698843755},{"schema":1537961639183,"dictionaries":["bn-BD@dictionaries.addons.mozilla.org"],"id":"bn-BD","last_modified":1539698843700},{"schema":1537961639183,"dictionaries":["bg-BG@dictionaries.addons.mozilla.org"],"id":"bg","last_modified":1539698843646},{"schema":1537961639183,"dictionaries":["be@dictionaries.addons.mozilla.org"],"id":"be","last_modified":1539698843592},{"schema":1537961639183,"dictionaries":["az@dictionaries.addons.mozilla.org"],"id":"az","last_modified":1539698843539},{"schema":1537961639183,"dictionaries":["asturianu@dictionaries.addons.mozilla.org"],"id":"ast","last_modified":1539698843485},{"schema":1537961639183,"dictionaries":["as-IN@dictionaries.addons.mozilla.org"],"id":"as","last_modified":1539698843431},{"schema":1537961639183,"dictionaries":["ar@dictionaries.addons.mozilla.org"],"id":"ar","last_modified":1539698843376},{"schema":1537961639183,"dictionaries":["an-ES@dictionaries.addons.mozilla.org"],"id":"an","last_modified":1539698843321},{"schema":1537961639183,"dictionaries":["af-ZA@dictionaries.addons.mozilla.org"],"id":"af","last_modified":1539698843264}]}
\ No newline at end of file
--- a/services/settings/dumps/main/moz.build
+++ b/services/settings/dumps/main/moz.build
@@ -1,11 +1,12 @@
 # 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/.
 
 FINAL_TARGET_FILES.defaults.settings.main += [
     'example.json',
+    'language-dictionaries.json',
     'onboarding.json',
 ]
 
 if CONFIG['MOZ_BUILD_APP'] == 'browser':
     DIST_SUBDIR = 'browser'