Bug 1518514 - Correctly read and parse list.json in search engine manager. r=nalexander

Differential Revision: https://phabricator.services.mozilla.com/D15992

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Michael Kaply 2019-01-10 19:07:18 +00:00
Родитель cab631fd11
Коммит 4c3dd8e52e
1 изменённых файлов: 54 добавлений и 61 удалений

Просмотреть файл

@ -441,7 +441,10 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
try {
final JSONObject json = new JSONObject(FileUtils.readStringFromInputStreamAndCloseStream(in, MAX_LISTJSON_SIZE));
// Get the region used to fence search engines.
// Get the current language
final String languageTag = Locales.getLanguageTag(Locale.getDefault());
// Get the current region
String region = fetchCountryCode();
// Store the result, even if it's empty. If we fail to get a region, we never
@ -451,26 +454,23 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
.putString(PREF_REGION_KEY, (region == null ? "" : region))
.apply();
if (region != null) {
if (json.has(region)) {
final JSONObject regionData = json.getJSONObject(region);
if (regionData.has("searchDefault")) {
Log.d(LOG_TAG, "Found region-specific default engine name in browsersearch.json.");
return regionData.getString("searchDefault");
}
}
}
final JSONObject locales = json.getJSONObject("locales");
// Either we have no geoip region, or we didn't find the right region and we are falling back to the default.
if (json.has("default")) {
final JSONObject defaultData = json.getJSONObject("default");
if (defaultData.has("searchDefault")) {
Log.d(LOG_TAG, "Found default engine name in list.json.");
return defaultData.getString("searchDefault");
if (locales.has(languageTag)) {
final JSONObject regions = locales.getJSONObject(languageTag);
if (!regions.has(region)) {
// Region doesn't exist, use default.
// default always exists.
region = "default";
}
final JSONObject regionData = regions.getJSONObject(region);
if (regionData.has("searchDefault")) {
return regionData.getString("searchDefault");
}
}
// We should never get here
Log.e(LOG_TAG, "Error missing defaultSearch in list.json");
// Falling back to the overall default
final JSONObject defaultData = json.getJSONObject("default");
return defaultData.getString("searchDefault");
} catch (IOException e) {
Log.e(LOG_TAG, "Error getting search engine name from list.json", e);
} catch (JSONException e) {
@ -603,18 +603,44 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
IOUtils.safeStreamClose(in);
}
try {
String region = GeckoSharedPrefs.forApp(context).getString(PREF_REGION_KEY, null);
final String languageTag = Locales.getLanguageTag(Locale.getDefault());
JSONArray engines;
if (json.has(region)) {
engines = json.getJSONObject(region).getJSONArray("visibleDefaultEngines");
String region = fetchCountryCode();
final JSONObject locales = json.getJSONObject("locales");
JSONArray jsonEngines;
if (locales.has(languageTag)) {
final JSONObject regions = locales.getJSONObject(languageTag);
if (!regions.has(region)) {
// Region doesn't exist, use default.
// default always exists.
region = "default";
}
jsonEngines = regions.getJSONObject(region).getJSONArray("visibleDefaultEngines");
} else {
engines = json.getJSONObject("default").getJSONArray("visibleDefaultEngines");
// Falling back to the overall default
jsonEngines = locales.getJSONObject("default").getJSONArray("visibleDefaultEngines");
}
for (int i = 0; i < engines.length(); i++) {
final InputStream pluginIn = getInputStreamFromSearchPluginsJar(engines.getString(i) + ".xml");
ArrayList<String> engines = new ArrayList<String>();
if (json.getJSONObject("regionOverrides").has(region)) {
final JSONObject regionOverride = json.getJSONObject("regionOverrides").getJSONObject(fetchCountryCode());
for (int i = 0; i < jsonEngines.length(); i++) {
final String engineName = jsonEngines.getString(i);
if (regionOverride.has(engineName)) {
engines.add(regionOverride.getString(engineName));
} else {
engines.add(engineName);
}
}
}
for (int i = 0; i < engines.size(); i++) {
final InputStream pluginIn = getInputStreamFromSearchPluginsJar(engines.get(i) + ".xml");
if (pluginIn != null) {
final SearchEngine engine = createEngineFromInputStream(engines.getString(i), pluginIn);
final SearchEngine engine = createEngineFromInputStream(engines.get(i), pluginIn);
if (engine != null && engine.getName().equals(name)) {
return engine;
}
@ -703,29 +729,8 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
* @return InputStream for file.
*/
private InputStream getInputStreamFromSearchPluginsJar(String fileName) {
final Locale locale = Locale.getDefault();
// First, try a file path for the full locale.
final String languageTag = Locales.getLanguageTag(locale);
String url = getSearchPluginsJarURL(context, languageTag, fileName);
InputStream in = GeckoJarReader.getStream(context, url);
if (in != null) {
return in;
}
// If that doesn't work, try a file path for just the language.
final String language = Locales.getLanguage(locale);
if (!languageTag.equals(language)) {
url = getSearchPluginsJarURL(context, language, fileName);
in = GeckoJarReader.getStream(context, url);
if (in != null) {
return in;
}
}
// Finally, fall back to default locale defined in chrome registry.
url = getSearchPluginsJarURL(context, getFallbackLocale(), fileName);
final String path = "chrome/chrome/searchplugins/" + fileName;
final String url = GeckoJarReader.getJarURL(context, path);
return GeckoJarReader.getStream(context, url);
}
@ -769,18 +774,6 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
return fallbackLocale;
}
/**
* Gets the jar URL for a file in the searchplugins directory.
*
* @param locale String representing the Gecko locale (e.g. "en-US").
* @param fileName The name of the file to read.
* @return URL for jar file.
*/
private static String getSearchPluginsJarURL(Context context, String locale, String fileName) {
final String path = "chrome/" + locale + "/locale/" + locale + "/browser/searchplugins/" + fileName;
return GeckoJarReader.getJarURL(context, path);
}
private BufferedReader getBufferedReader(InputStream in) {
try {
return new BufferedReader(new InputStreamReader(in, "UTF-8"));