Bug 1300201 - Switch Fennec to use list.json. r?sebastian,r?flod draft
authorMichael Kaply <mozilla@kaply.com>
Thu, 09 Mar 2017 14:58:57 -0600
changeset 496697 08177e5091abc0797f063b6d40a5a5d3c53541e3
parent 496008 c3b67a7430304393d2691ffff19c459e603cbb46
child 548667 5de39b8996133830549ee773d2638ae1888749a0
push id48656
push usermozilla@kaply.com
push dateFri, 10 Mar 2017 12:41:00 +0000
reviewerssebastian, flod
bugs1300201
milestone55.0a1
Bug 1300201 - Switch Fennec to use list.json. r?sebastian,r?flod MozReview-Commit-ID: JNtFSCOQhJ
mobile/android/base/java/org/mozilla/gecko/search/SearchEngineManager.java
mobile/locales/Makefile.in
mobile/locales/jar.mn
mobile/locales/search/list.json
--- a/mobile/android/base/java/org/mozilla/gecko/search/SearchEngineManager.java
+++ b/mobile/android/base/java/org/mozilla/gecko/search/SearchEngineManager.java
@@ -17,16 +17,17 @@ import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.GeckoProfile;
 import org.mozilla.gecko.GeckoSharedPrefs;
 import org.mozilla.gecko.Locales;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.distribution.Distribution;
 import org.mozilla.gecko.util.FileUtils;
 import org.mozilla.gecko.util.GeckoJarReader;
 import org.mozilla.gecko.util.HardwareUtils;
+import org.mozilla.gecko.util.IOUtils;
 import org.mozilla.gecko.util.RawResource;
 import org.mozilla.gecko.util.StringUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedReader;
 import java.io.File;
@@ -37,16 +38,18 @@ import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.lang.ref.WeakReference;
 import java.net.HttpURLConnection;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Locale;
+import org.json.JSONObject;
+import org.json.JSONArray;
 
 /**
  * This class is not thread-safe, except where otherwise noted.
  *
  * This class contains a reference to {@link Context} - DO NOT LEAK!
  */
 public class SearchEngineManager implements SharedPreferences.OnSharedPreferenceChangeListener {
     private static final String LOG_TAG = "GeckoSearchEngineManager";
@@ -61,16 +64,19 @@ public class SearchEngineManager impleme
     private static final String PREF_DEFAULT_ENGINE_KEY = "search.engines.defaultname";
 
     // Key for shared preference that stores search region.
     private static final String PREF_REGION_KEY = "search.region";
 
     // URL for the geo-ip location service. Keep in sync with "browser.search.geoip.url" perference in Gecko.
     private static final String GEOIP_LOCATION_URL = "https://location.services.mozilla.com/v1/country?key=" + AppConstants.MOZ_MOZILLA_API_KEY;
 
+    // The API we're using requires a file size, so set an arbitrarily large one
+    public static final int MAX_LISTJSON_SIZE = 8192;
+
     // This should go through GeckoInterface to get the UA, but the search activity
     // doesn't use a GeckoView yet. Until it does, get the UA directly.
     private static final String USER_AGENT = HardwareUtils.isTablet() ?
         AppConstants.USER_AGENT_FENNEC_TABLET : AppConstants.USER_AGENT_FENNEC_MOBILE;
 
     private final Context context;
     private final Distribution distribution;
     @Nullable private volatile SearchEngineCallback changeCallback;
@@ -554,54 +560,63 @@ public class SearchEngineManager impleme
         }
 
         return createEngineFromFileList(files.toArray(new File[files.size()]), name);
     }
 
     /**
      * Creates a SearchEngine instance for a search plugin shipped in the locale.
      *
-     * This method reads the list of search plugin file names from list.txt, then
+     * This method reads the list of search plugin file names from list.json, then
      * iterates through the files, creating SearchEngine instances until it finds one
      * with the right name. Unfortunately, we need to do this because there is no
      * other way to map the search engine "name" to the file for the search plugin.
      *
      * @param name Search engine name.
      * @return SearchEngine instance for name.
      */
     private SearchEngine createEngineFromLocale(String name) {
-        final InputStream in = getInputStreamFromSearchPluginsJar("list.txt");
+        final InputStream in = getInputStreamFromSearchPluginsJar("list.json");
         if (in == null) {
             return null;
         }
-        final BufferedReader br = getBufferedReader(in);
-
+        JSONObject json;
+        try {
+            json = new JSONObject(FileUtils.readStringFromInputStreamAndCloseStream(in, MAX_LISTJSON_SIZE));
+        } catch (IOException e) {
+            Log.e(LOG_TAG, "Error reading list.json", e);
+            return null;
+        } catch (JSONException e) {
+            Log.e(LOG_TAG, "Error parsing list.json", e);
+            return null;
+        } finally {
+            IOUtils.safeStreamClose(in);
+        }
         try {
-            String identifier;
-            while ((identifier = br.readLine()) != null) {
-                final InputStream pluginIn = getInputStreamFromSearchPluginsJar(identifier + ".xml");
-                // pluginIn can be null if the xml file doesn't exist which
-                // can happen with :hidden plugins
+            String region = GeckoSharedPrefs.forApp(context).getString(PREF_REGION_KEY, null);
+
+            JSONArray engines;
+            if (json.has(region)) {
+                engines = json.getJSONObject(region).getJSONArray("visibleDefaultEngines");
+            } else {
+                engines = json.getJSONObject("default").getJSONArray("visibleDefaultEngines");
+            }
+            for (int i = 0; i < engines.length(); i++) {
+                final InputStream pluginIn = getInputStreamFromSearchPluginsJar(engines.getString(i) + ".xml");
                 if (pluginIn != null) {
-                  final SearchEngine engine = createEngineFromInputStream(identifier, pluginIn);
-                  if (engine != null && engine.getName().equals(name)) {
-                      return engine;
+                    final SearchEngine engine = createEngineFromInputStream(engines.getString(i), pluginIn);
+                    if (engine != null && engine.getName().equals(name)) {
+                        return engine;
+                    }
                   }
-                }
-            }
-        } catch (Throwable e) {
-            Log.e(LOG_TAG, "Error creating shipped search engine from name: " + name, e);
-        } finally {
-            try {
-                br.close();
-            } catch (IOException e) {
-                // Ignore.
-            }
-        }
-        return null;
+              }
+          } catch (Throwable e) {
+              Log.e(LOG_TAG, "Error creating shipped search engine from name: " + name, e);
+          }
+          return null;
     }
 
     /**
      * Creates a SearchEngine instance for a search plugin in the profile directory.
      *
      * This method iterates through the profile searchplugins directory, creating
      * SearchEngine instances until it finds one with the right name.
      *
--- a/mobile/locales/Makefile.in
+++ b/mobile/locales/Makefile.in
@@ -41,18 +41,17 @@ SUBMAKEFILES += \
 #    gmake -C $obj/mobile/locales
 ###########################################################################
 search-jar-default: search-jar
 
 
 ###########################################################################
 ## Searchlist plugin config
 plugin-file-array = \
-  $(wildcard $(LOCALE_SRCDIR)/searchplugins/list.txt) \
-  $(srcdir)/en-US/searchplugins/list.txt \
+  $(srcdir)/search/list.json \
   $(NULL)
 
 ###########################################################################
 plugin_file    = $(firstword $(plugin-file-array))
 plugin-file-ts = $(tgt-gendir)/$(subst $(topsrcdir)/,$(NULL),$(plugin_file)).ts
 
 GARBAGE += $(plugin-file-ts)
 # ---------------------------------------------------------------------------
@@ -75,32 +74,32 @@ plugin-file-ts-preqs = \
 search-jar-common = tmp-search.jar.mn
 search-jar        = $(tgt-gendir)/$(search-jar-common)
 search-jar-ts     = $(search-jar).ts
 
 GARBAGE += $(search-jar) $(search-jar-ts) $(search-jar-common)
 # ---------------------------------------------------------------------------
 # search-jar contains a list of providers for the search plugin
 ###########################################################################
-SEARCH_PLUGINS = $(shell cat $(plugin_file))
-SEARCH_PLUGINS := $(subst :hidden,,$(SEARCH_PLUGINS))
+SEARCH_PLUGINS := $(shell $(call py_action,output_searchplugins_list,$(srcdir)/search/list.json $(AB_CD)))
 $(call errorIfEmpty,SEARCH_PLUGINS)
 
 search-jar-preqs = \
   $(plugin-file-ts) \
   $(if $(IS_LANGUAGE_REPACK),FORCE) \
   $(NULL)
 
 .PHONY: search-jar
 search-jar: $(search-jar)
 $(search-jar): $(search-jar-preqs)
 	@echo '\nGenerating: search-jar'
 	printf '$(AB_CD).jar:' > $@
 	ln -fn $@ .
 	printf '$(foreach plugin,$(SEARCH_PLUGINS),$(subst __PLUGIN_SUBST__,$(plugin), \n locale/$(AB_CD)/browser/searchplugins/__PLUGIN_SUBST__.xml (__PLUGIN_SUBST__.xml)))' >>  $@
+	printf '\n locale/$(AB_CD)/browser/searchplugins/list.json (list.json)' >> $@
 	@echo   >> $@
 
 ###################
 search-dir-deps = \
   $(plugin-file) \
   $(dir-chrome) \
   $(NULL)
 
@@ -110,20 +109,22 @@ search-preqs =\
   $(search-jar) \
   $(search-dir-deps) \
   $(if $(IS_LANGUAGE_REPACK),FORCE) \
   $(GLOBAL_DEPS) \
   $(NULL)
 
 .PHONY: searchplugins
 searchplugins: $(search-preqs)
+	$(call py_action,generate_searchjson,$(srcdir)/search/list.json $(AB_CD) $(tgt-gendir)/list.json)
 	$(call py_action,jar_maker,\
           $(QUIET) -d $(FINAL_TARGET) \
           -s $(topsrcdir)/$(relativesrcdir)/en-US/searchplugins \
           -s $(LOCALE_SRCDIR)/searchplugins \
+          -s $(tgt-gendir) \
           $(MAKE_JARS_FLAGS) $(search-jar))
 	$(TOUCH) $@
 
 include $(topsrcdir)/config/rules.mk
 
 
 #############
 libs-preqs =\
--- a/mobile/locales/jar.mn
+++ b/mobile/locales/jar.mn
@@ -2,17 +2,16 @@
 # 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/.
 
 
 @AB_CD@.jar:
 % locale browser @AB_CD@ %locale/@AB_CD@/browser/
   locale/@AB_CD@/browser/region.properties        (%chrome/region.properties)
-  locale/@AB_CD@/browser/searchplugins/list.txt   (%searchplugins/list.txt)
 
 # Fennec-specific overrides of generic strings
   locale/@AB_CD@/browser/netError.dtd             (%overrides/netError.dtd)
 % override chrome://global/locale/netError.dtd    chrome://browser/locale/netError.dtd
   locale/@AB_CD@/browser/appstrings.properties    (%overrides/appstrings.properties)
 % override chrome://global/locale/appstrings.properties chrome://browser/locale/appstrings.properties
   locale/@AB_CD@/browser/passwordmgr.properties    (%overrides/passwordmgr.properties)
 % override chrome://passwordmgr/locale/passwordmgr.properties chrome://browser/locale/passwordmgr.properties
new file mode 100644
--- /dev/null
+++ b/mobile/locales/search/list.json
@@ -0,0 +1,688 @@
+{
+  "default": {
+    "visibleDefaultEngines": [
+      "google", "yahoo", "bing", "amazondotcom", "duckduckgo", "twitter", "wikipedia"
+    ]
+  },
+  "regionOverrides": {
+    "US": {
+      "google": "google-nocodes"
+    },
+    "CA": {
+      "google": "google-nocodes"
+    },
+    "KZ": {
+      "google": "google-nocodes"
+    },
+    "BY": {
+      "google": "google-nocodes"
+    },
+    "RU": {
+      "google": "google-nocodes"
+    },
+    "TR": {
+      "google": "google-nocodes"
+    },
+    "UA": {
+      "google": "google-nocodes"
+    },
+    "CN": {
+      "google": "google-nocodes"
+    },
+    "TW": {
+      "google": "google-nocodes"
+    },
+    "HK": {
+      "google": "google-nocodes"
+    }
+  },
+  "locales": {
+    "an": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-es", "bing", "twitter", "wikipedia-an"
+        ]
+      }
+    },
+    "ar": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "amazondotcom", "twitter", "wikipedia-ar"
+        ]
+      }
+    },
+    "as": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-in", "bing", "amazon-in", "wikipedia-as"
+        ]
+      }    
+    },
+    "ast": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-es", "bing", "amazondotcom", "twitter", "wikipedia-ast"
+        ]
+      }
+    },
+    "az": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "bing", "amazondotcom", "azerdict", "duckduckgo", "wikipedia-az"
+        ]
+      }
+    },
+    "be": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "be.wikipedia.org", "bing", "tut.by", "yahoo", "yandex.by"
+        ]
+      }
+    },
+    "bg": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "wikipedia-bg"
+        ]
+      }
+    },
+    "bn-IN": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-in", "bing", "amazondotcom", "rediff", "wikipedia-bn"
+        ]
+      }
+    },
+    "br": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-france", "bing", "twitter", "wikipedia-br"
+        ]
+      }
+    },
+    "ca": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "twitter", "wikipedia-ca", "diec2"
+        ]
+      }
+    },
+    "cak": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-espanol", "amazondotcom", "duckduckgo", "wikipedia-es"
+        ]
+      }
+    },
+    "cs": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "duckduckgo", "heureka-cz", "mapy-cz", "seznam-cz", "twitter", "wikipedia-cz"
+        ]
+      }
+    },
+    "cy": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-en-GB", "bing", "amazon-en-GB", "duckduckgo", "wikipedia-cy"
+        ]
+      }
+    },
+    "da": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "amazon-co-uk", "twitter", "wikipedia-da"
+        ]
+      }
+    },
+    "de": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-de", "bing", "amazon-de", "duckduckgo", "qwant", "twitter", "wikipedia-de"
+        ]
+      }
+    },
+    "dsb": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-de", "bing", "amazon-de", "twitter", "wikipedia-dsb"
+        ]
+      }
+    },
+    "el": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "skroutz", "twitter", "wikipedia-el"
+        ]
+      }
+    },
+    "en-GB": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-en-GB",  "bing", "amazon-en-GB", "duckduckgo", "qwant", "twitter", "wikipedia"
+        ]
+      }
+    },
+    "en-US": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "amazondotcom", "duckduckgo", "twitter", "wikipedia"
+        ]
+      },
+      "US": {
+        "visibleDefaultEngines": [
+          "yahoo", "google-nocodes", "bing", "amazondotcom", "duckduckgo", "twitter", "wikipedia"
+        ]
+      },
+      "CA": {
+        "visibleDefaultEngines": [
+          "google-nocodes", "yahoo", "bing", "amazondotcom", "duckduckgo", "twitter", "wikipedia"
+        ]
+      }
+    },
+    "en-ZA": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "twitter", "wikipedia"
+        ]
+      }
+    },
+    "eo": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "duckduckgo", "reta-vortaro", "twitter", "wikipedia-eo"
+        ]
+      }
+    },
+    "es-AR": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "mercadolibre-ar", "twitter", "wikipedia-es"
+        ]
+      }
+    },
+    "es-CL": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-cl", "bing", "drae", "mercadolibre-cl", "twitter", "wikipedia-es"
+        ]
+      }
+    },
+    "es-ES": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-es", "bing", "duckduckgo", "twitter", "wikipedia-es"
+        ]
+      }
+    },
+    "es-MX": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-mx", "bing", "amazondotcom", "duckduckgo", "mercadolibre-mx", "twitter", "wikipedia-es"
+        ]
+      }
+    },
+    "et": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "amazon-co-uk", "twitter", "wikipedia-et"
+        ]
+      }
+    },
+    "eu": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-es", "bing", "elebila", "wikipedia-eu"
+        ]
+      }
+    },
+    "fa": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "wikipedia-fa", "yahoo"
+        ]
+      }
+    },
+    "ff": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-france", "bing", "amazon-france", "wikipedia-fr"
+        ]
+      }
+    },
+    "fi": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "amazondotcom", "twitter", "wikipedia-fi", "yahoo-fi"
+        ]
+      }
+    },
+    "fr": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-france", "bing", "duckduckgo", "qwant", "twitter", "wikipedia-fr"
+        ]
+      }
+    },
+    "fy-NL": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "wikipedia-fy-NL", "bolcom-fy-NL"
+        ]
+      }
+    },
+    "ga-IE": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "amazon-en-GB", "tearma", "twitter", "wikipedia-ga-IE"
+        ]
+      }
+    },
+    "gd": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-en-GB", "bing", "duckduckgo", "faclair-beag", "wikipedia-gd"
+        ]
+      }
+    },
+    "gl": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-es", "bing", "amazondotcom", "twitter", "wikipedia-gl"
+        ]
+      }
+    },
+    "gn": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-espanol", "bing", "amazondotcom", "twitter", "wikipedia-gn"
+        ]
+      }
+    },
+    "gu-IN": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-in", "bing", "amazon-in", "wikipedia-gu"
+        ]
+      }
+    },
+    "he": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "amazondotcom", "twitter", "wikipedia-he"
+        ]
+      }
+    },
+    "hi-IN": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-in", "bing", "amazon-in", "twitter", "wikipedia-hi"
+        ]
+      }
+    },
+    "hr": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "amazon-en-GB", "duckduckgo", "twitter", "wikipedia-hr"
+        ]
+      }
+    },
+    "hsb": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-de", "bing", "amazon-de", "twitter", "wikipedia-hsb"
+        ]
+      }
+    },
+    "hu": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "sztaki-en-hu", "vatera", "twitter", "wikipedia-hu"
+        ]
+      }
+    },
+    "hy-AM": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "amazondotcom", "list-am", "wikipedia-hy-AM"
+        ]
+      }
+    },
+    "id": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-id", "bing", "twitter", "wikipedia-id"
+        ]
+      }
+    },
+    "is": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "amazondotcom", "leit-is", "wikipedia-is"
+        ]
+      }
+    },
+    "it": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "twitter", "wikipedia-it"
+        ]
+      }
+    },
+    "ja": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "amazon-jp", "bing", "twitter-ja", "wikipedia-ja", "yahoo-jp"
+        ]
+      }
+    },
+    "ka": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "amazondotcom", "duckduckgo", "wikipedia-ka"
+        ]
+      }
+    },
+    "kab": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-france", "bing", "wikipedia-kab"
+        ]
+      }
+    },
+    "kk": {
+      "default": {
+        "visibleDefaultEngines": [
+          "yandex", "google", "yahoo", "bing", "twitter", "wikipedia-kk"
+        ]
+      }
+    },
+    "km": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "amazondotcom", "twitter", "wikipedia-km"
+        ]
+      }
+    },
+    "kn": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-in", "bing", "amazon-in", "twitter", "wikipedia-kn", "wiktionary-kn"
+        ]
+      }
+    },
+    "ko": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "danawa-kr", "twitter", "daum-kr", "naver-kr"
+        ]
+      }
+    },
+    "lij": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "amazondotcom", "twitter", "wikipedia"
+        ]
+      }
+    },
+    "lo": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "twitter", "wikipedia-lo"
+        ]
+      }
+    },
+    "lt": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "twitter", "wikipedia-lt"
+        ]
+      }
+    },
+    "lv": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "salidzinilv", "sslv", "twitter", "wikipedia-lv"
+        ]
+      }
+    },
+    "mai": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-in", "bing", "amazon-in", "twitter", "wikipedia-hi"
+        ]
+      }
+    },
+    "ml": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-in", "bing", "duckduckgo", "twitter", "wikipedia-ml"
+        ]
+      }
+    },
+    "mr": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-in", "bing", "amazon-in", "rediff", "wikipedia-mr"
+        ]
+      }
+    },
+    "ms": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "amazondotcom", "twitter", "wikipedia-ms"
+        ]
+      }
+    },
+    "my": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "amazondotcom", "twitter", "wikipedia-my"
+        ]
+      }
+    },
+    "nb-NO": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "duckduckgo", "gulesider-mobile-NO", "twitter", "wikipedia-NO"
+        ]
+      }
+    },
+    "ne-NP": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "twitter", "wikipedia-ne"
+        ]
+      }
+    },
+    "nl": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "wikipedia-nl", "bolcom-nl"
+        ]
+      }
+    },
+    "nn-NO": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "duckduckgo", "gulesider-mobile-NO", "twitter", "wikipedia-NN"
+        ]
+      }
+    },
+    "or": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-in", "bing", "amazon-in", "wikipedia-or", "wiktionary-or"
+        ]
+      }
+    },
+    "pa-IN": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-in", "bing", "wikipedia-pa"
+        ]
+      }
+    },
+    "pl": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "bing", "duckduckgo", "twitter", "wikipedia-pl"
+        ]
+      }
+    },
+    "pt-BR": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-br", "bing", "twitter", "wikipedia-br"
+        ]
+      }
+    },
+    "pt-PT": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "wikipedia-ptpt"
+        ]
+      }
+    },
+    "rm": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-ch", "bing", "duckduckgo", "leo_ende_de", "pledarigrond", "wikipedia-rm"
+        ]
+      }
+    },
+    "ro": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "twitter", "wikipedia-ro"
+        ]
+      }
+    },
+    "ru": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yandex-ru", "twitter", "wikipedia-ru"
+        ]
+      }
+    },
+    "sk": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "azet-sk", "slovnik-sk", "twitter", "wikipedia-sk"
+        ]
+      }
+    },
+    "sl": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "ceneje", "odpiralni", "twitter", "wikipedia-sl"
+        ]
+      }
+    },
+    "son": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-france", "bing", "amazon-fr", "twitter", "wikipedia-fr"
+        ]
+      }
+    },
+    "sq": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "amazon-en-GB", "twitter", "wikipedia-sq"
+        ]
+      }
+    },
+    "sr": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "duckduckgo", "twitter", "wikipedia-sr"
+        ]
+      }
+    },
+    "sv-SE": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "prisjakt-sv-SE", "twitter", "wikipedia-sv-SE"
+        ]
+      }
+    },
+    "ta": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-in", "bing", "amazon-in", "duckduckgo", "wikipedia-ta", "wiktionary-ta"
+        ]
+      }
+    },
+    "te": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-in", "bing", "amazon-in", "wikipedia-te", "wiktionary-te"
+        ]
+      }
+    },
+    "th": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "twitter", "wikipedia-th"
+        ]
+      }
+    },
+    "tr": {
+      "default": {
+        "visibleDefaultEngines": [
+          "yandex-tr", "google", "twitter", "wikipedia-tr"
+        ]
+      }
+    },
+    "uk": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "twitter", "wikipedia-uk", "yandex-market"
+        ]
+      }
+    },
+    "ur": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo-in", "bing", "amazon-in", "duckduckgo", "twitter", "wikipedia-ur"
+        ]
+      }
+    },
+    "uz": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "amazondotcom", "twitter", "wikipedia-uz"
+        ]
+      }
+    },
+    "vi": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "amazondotcom", "twitter", "wikipedia-vi"
+        ]
+      }
+    },
+    "xh": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "yahoo", "bing", "twitter", "wikipedia"
+        ]
+      }
+    },
+    "zh-CN": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "baidu", "bing", "taobao", "wikipedia-zh-CN"
+        ]
+      }
+    },
+    "zh-TW": {
+      "default": {
+        "visibleDefaultEngines": [
+          "google", "bing", "duckduckgo", "wikipedia-zh-TW"
+        ]
+      }
+    }
+  }
+}