From 77f33bf9f9ac94afde188450fff0611c233a3b0a Mon Sep 17 00:00:00 2001 From: Michael Kaply Date: Thu, 9 Mar 2017 14:58:57 -0600 Subject: [PATCH] Bug 1300201 - Switch Fennec to use list.json. r=sebastian,r=flod MozReview-Commit-ID: JNtFSCOQhJ --HG-- extra : rebase_source : ee63b3d2bc9f82a0e0a9c8ca4ef752e7a32106b9 --- .../gecko/search/SearchEngineManager.java | 53 +- mobile/locales/Makefile.in | 9 +- mobile/locales/jar.mn | 1 - mobile/locales/search/list.json | 696 ++++++++++++++++++ 4 files changed, 735 insertions(+), 24 deletions(-) create mode 100644 mobile/locales/search/list.json diff --git a/mobile/android/base/java/org/mozilla/gecko/search/SearchEngineManager.java b/mobile/android/base/java/org/mozilla/gecko/search/SearchEngineManager.java index 67e7f45d86f7..3cc413e1fba6 100644 --- a/mobile/android/base/java/org/mozilla/gecko/search/SearchEngineManager.java +++ b/mobile/android/base/java/org/mozilla/gecko/search/SearchEngineManager.java @@ -22,6 +22,7 @@ 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; @@ -42,6 +43,8 @@ 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. @@ -66,6 +69,9 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference // 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() ? @@ -559,7 +565,7 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference /** * 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. @@ -568,33 +574,42 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference * @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 { - 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 + 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 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; } diff --git a/mobile/locales/Makefile.in b/mobile/locales/Makefile.in index d4f0237b9f3a..c4a62cf13b82 100644 --- a/mobile/locales/Makefile.in +++ b/mobile/locales/Makefile.in @@ -46,8 +46,7 @@ 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) ########################################################################### @@ -80,8 +79,7 @@ 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 = \ @@ -96,6 +94,7 @@ $(search-jar): $(search-jar-preqs) 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 >> $@ ################### @@ -115,10 +114,12 @@ search-preqs =\ .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) $@ diff --git a/mobile/locales/jar.mn b/mobile/locales/jar.mn index 0e65e4b2c24a..e94888548ef0 100644 --- a/mobile/locales/jar.mn +++ b/mobile/locales/jar.mn @@ -7,7 +7,6 @@ @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) diff --git a/mobile/locales/search/list.json b/mobile/locales/search/list.json new file mode 100644 index 000000000000..c0c12ee04218 --- /dev/null +++ b/mobile/locales/search/list.json @@ -0,0 +1,696 @@ +{ + "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", "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" + ] + } + }, + "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" + ] + } + }, + "trs": { + "default": { + "searchDefault": "Google", + "visibleDefaultEngines": [ + "amazondotcom", "bing", "google", "twitter", "wikipedia-es", "yahoo-espanol" + ] + } + }, + "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" + ] + } + } + } +}