зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1091728 - Use correct gecko default search engine in search activity. r=rnewman
This commit is contained in:
Родитель
9bb10ffa42
Коммит
611d572f7f
|
@ -6920,7 +6920,7 @@ var SearchEngines = {
|
|||
PREF_SUGGEST_PROMPTED: "browser.search.suggest.prompted",
|
||||
|
||||
// Shared preference key used for search activity default engine.
|
||||
PREF_SEARCH_ACTIVITY_ENGINE_KEY: "search.engines.default",
|
||||
PREF_SEARCH_ACTIVITY_ENGINE_KEY: "search.engines.defaultname",
|
||||
|
||||
init: function init() {
|
||||
Services.obs.addObserver(this, "SearchEngines:Add", false);
|
||||
|
@ -7060,34 +7060,7 @@ var SearchEngines = {
|
|||
|
||||
// Updates the search activity pref when the default engine changes.
|
||||
_setSearchActivityDefaultPref: function _setSearchActivityDefaultPref(engine) {
|
||||
// Helper function copied from nsSearchService.js. This is the logic that is used
|
||||
// to create file names for search plugin XML serialized to disk.
|
||||
function sanitizeName(aName) {
|
||||
const maxLength = 60;
|
||||
const minLength = 1;
|
||||
let name = aName.toLowerCase();
|
||||
name = name.replace(/\s+/g, "-");
|
||||
name = name.replace(/[^-a-z0-9]/g, "");
|
||||
|
||||
if (name.length < minLength) {
|
||||
// Well, in this case, we're kinda screwed. In this case, the search service
|
||||
// generates a random file name, so to do this the right way, we'd need
|
||||
// to open up search.json and see what file name is stored.
|
||||
Cu.reportError("Couldn't create search plugin file name from engine name: " + aName);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Force max length.
|
||||
return name.substring(0, maxLength);
|
||||
}
|
||||
|
||||
let identifier = engine.identifier;
|
||||
if (identifier === null) {
|
||||
// The identifier will be null for non-built-in engines. In this case, we need to
|
||||
// figure out an identifier to store from the engine name.
|
||||
identifier = sanitizeName(engine.name);
|
||||
}
|
||||
SharedPreferences.forApp().setCharPref(this.PREF_SEARCH_ACTIVITY_ENGINE_KEY, identifier);
|
||||
SharedPreferences.forApp().setCharPref(this.PREF_SEARCH_ACTIVITY_ENGINE_KEY, engine.name);
|
||||
},
|
||||
|
||||
// Display context menu listing names of the search engines available to be added.
|
||||
|
|
|
@ -17,9 +17,4 @@ package org.mozilla.search;
|
|||
public class Constants {
|
||||
|
||||
public static final String ABOUT_BLANK = "about:blank";
|
||||
|
||||
// TODO: Localize this with region.properties (or a similar solution). See bug 1065306.
|
||||
public static final String DEFAULT_ENGINE_IDENTIFIER = "yahoo";
|
||||
|
||||
public static final String PREF_SEARCH_ENGINE_KEY = "search.engines.default";
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.mozilla.gecko.R;
|
|||
import org.mozilla.gecko.Telemetry;
|
||||
import org.mozilla.gecko.TelemetryContract;
|
||||
import org.mozilla.gecko.db.BrowserContract.SearchHistory;
|
||||
import org.mozilla.gecko.distribution.Distribution;
|
||||
import org.mozilla.gecko.health.BrowserHealthRecorder;
|
||||
import org.mozilla.search.autocomplete.SearchBar;
|
||||
import org.mozilla.search.autocomplete.SuggestionsFragment;
|
||||
|
@ -101,7 +102,7 @@ public class SearchActivity extends LocaleAware.LocaleAwareFragmentActivity
|
|||
suggestionsFragment = (SuggestionsFragment) getSupportFragmentManager().findFragmentById(R.id.suggestions);
|
||||
postSearchFragment = (PostSearchFragment) getSupportFragmentManager().findFragmentById(R.id.postsearch);
|
||||
|
||||
searchEngineManager = new SearchEngineManager(this);
|
||||
searchEngineManager = new SearchEngineManager(this, Distribution.init(this));
|
||||
searchEngineManager.setChangeCallback(this);
|
||||
|
||||
// Initialize the fragments with the selected search engine.
|
||||
|
@ -279,7 +280,10 @@ public class SearchActivity extends LocaleAware.LocaleAwareFragmentActivity
|
|||
searchEngineManager.getEngine(new SearchEngineCallback() {
|
||||
@Override
|
||||
public void execute(SearchEngine engine) {
|
||||
postSearchFragment.startSearch(engine, query);
|
||||
// TODO: If engine is null, we should show an error message.
|
||||
if (engine != null) {
|
||||
postSearchFragment.startSearch(engine, query);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -293,6 +297,10 @@ public class SearchActivity extends LocaleAware.LocaleAwareFragmentActivity
|
|||
*/
|
||||
@Override
|
||||
public void execute(SearchEngine engine) {
|
||||
// TODO: If engine is null, we should show an error message.
|
||||
if (engine == null) {
|
||||
return;
|
||||
}
|
||||
this.engine = engine;
|
||||
suggestionsFragment.setEngine(engine);
|
||||
searchBar.setEngine(engine);
|
||||
|
|
|
@ -52,7 +52,9 @@ public class SearchEngine {
|
|||
"document.getElementsByTagName('head')[0].appendChild(tag);" +
|
||||
"tag.innerText='%s'})();";
|
||||
|
||||
// The Gecko search identifier. This will be null for engines that don't ship with the locale.
|
||||
private final String identifier;
|
||||
|
||||
private String shortName;
|
||||
private String iconURL;
|
||||
|
||||
|
@ -189,7 +191,9 @@ public class SearchEngine {
|
|||
public String getInjectableJs() {
|
||||
final String css;
|
||||
|
||||
if (identifier.equals("bing")) {
|
||||
if (identifier == null) {
|
||||
css = "";
|
||||
} else if (identifier.equals("bing")) {
|
||||
css = "#mHeader{display:none}#contentWrapper{margin-top:0}";
|
||||
} else if (identifier.equals("google")) {
|
||||
css = "#sfcnt,#top_nav{display:none}";
|
||||
|
@ -247,7 +251,7 @@ public class SearchEngine {
|
|||
public String resultsUriForQuery(String query) {
|
||||
final Uri resultsUri = getResultsUri();
|
||||
if (resultsUri == null) {
|
||||
Log.e(LOG_TAG, "No results URL for search engine: " + identifier);
|
||||
Log.e(LOG_TAG, "No results URL for search engine: " + shortName);
|
||||
return "";
|
||||
}
|
||||
final String template = Uri.decode(resultsUri.toString());
|
||||
|
@ -261,7 +265,7 @@ public class SearchEngine {
|
|||
*/
|
||||
public String getSuggestionTemplate(String query) {
|
||||
if (suggestUri == null) {
|
||||
Log.e(LOG_TAG, "No suggestions template for search engine: " + identifier);
|
||||
Log.e(LOG_TAG, "No suggestions template for search engine: " + shortName);
|
||||
return "";
|
||||
}
|
||||
final String template = Uri.decode(suggestUri.toString());
|
||||
|
|
|
@ -6,15 +6,21 @@ package org.mozilla.search.providers;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants;
|
||||
import org.mozilla.gecko.BrowserLocaleManager;
|
||||
import org.mozilla.gecko.GeckoProfile;
|
||||
import org.mozilla.gecko.GeckoSharedPrefs;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.util.FileUtils;
|
||||
import org.mozilla.gecko.util.GeckoJarReader;
|
||||
import org.mozilla.gecko.util.RawResource;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.distribution.Distribution;
|
||||
import org.mozilla.search.Constants;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
|
@ -30,9 +36,16 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
|
||||
public class SearchEngineManager implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private static final String LOG_TAG = "SearchEngineManager";
|
||||
private static final String LOG_TAG = "GeckoSearchEngineManager";
|
||||
|
||||
// Gecko pref that defines the name of the default search engine.
|
||||
private static final String PREF_GECKO_DEFAULT_ENGINE = "browser.search.defaultenginename";
|
||||
|
||||
// Key for shared preference that stores default engine name.
|
||||
private static final String PREF_DEFAULT_ENGINE_KEY = "search.engines.defaultname";
|
||||
|
||||
private Context context;
|
||||
private Distribution distribution;
|
||||
private SearchEngineCallback changeCallback;
|
||||
private SearchEngine engine;
|
||||
|
||||
|
@ -40,11 +53,19 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
|
|||
public void execute(SearchEngine engine);
|
||||
}
|
||||
|
||||
public SearchEngineManager(Context context) {
|
||||
public SearchEngineManager(Context context, Distribution distribution) {
|
||||
this.context = context;
|
||||
this.distribution = distribution;
|
||||
GeckoSharedPrefs.forApp(context).registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a callback to be called when the default engine changes.
|
||||
*
|
||||
* @param callback SearchEngineCallback to be called after the search engine
|
||||
* changed. This will run on the UI thread.
|
||||
* Note: callback may be called with null engine.
|
||||
*/
|
||||
public void setChangeCallback(SearchEngineCallback changeCallback) {
|
||||
this.changeCallback = changeCallback;
|
||||
}
|
||||
|
@ -60,80 +81,230 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
|
|||
if (engine != null) {
|
||||
callback.execute(engine);
|
||||
} else {
|
||||
getEngineFromPrefs(callback);
|
||||
getDefaultEngine(callback);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
GeckoSharedPrefs.forApp(context).unregisterOnSharedPreferenceChangeListener(this);
|
||||
context = null;
|
||||
distribution = null;
|
||||
changeCallback = null;
|
||||
engine = null;
|
||||
}
|
||||
|
||||
private int ignorePreferenceChange = 0;
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
|
||||
if (!TextUtils.equals(Constants.PREF_SEARCH_ENGINE_KEY, key)) {
|
||||
if (!TextUtils.equals(PREF_DEFAULT_ENGINE_KEY, key)) {
|
||||
return;
|
||||
}
|
||||
getEngineFromPrefs(changeCallback);
|
||||
|
||||
if (ignorePreferenceChange > 0) {
|
||||
ignorePreferenceChange--;
|
||||
return;
|
||||
}
|
||||
|
||||
getDefaultEngine(changeCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up the current search engine in shared preferences.
|
||||
* Creates a SearchEngine instance and caches it for use on the main thread.
|
||||
* Runs a SearchEngineCallback on the main thread.
|
||||
*/
|
||||
private void runCallback(final SearchEngine engine, final SearchEngineCallback callback) {
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Cache engine for future calls to getEngine.
|
||||
SearchEngineManager.this.engine = engine;
|
||||
callback.execute(engine);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method finds and creates the default search engine. It will first look for
|
||||
* the default engine name, then create the engine from that name.
|
||||
*
|
||||
* @param callback a SearchEngineCallback to be called after successfully looking
|
||||
* To find the default engine name, we first look in shared preferences, then
|
||||
* the distribution (if one exists), and finally fall back to the localized default.
|
||||
*
|
||||
* @param callback SearchEngineCallback to be called after successfully looking
|
||||
* up the search engine. This will run on the UI thread.
|
||||
* Note: callback may be called with null engine.
|
||||
*/
|
||||
private void getEngineFromPrefs(final SearchEngineCallback callback) {
|
||||
final AsyncTask<Void, Void, SearchEngine> task = new AsyncTask<Void, Void, SearchEngine>() {
|
||||
private void getDefaultEngine(final SearchEngineCallback callback) {
|
||||
// This runnable is posted to the background thread.
|
||||
distribution.addOnDistributionReadyCallback(new Runnable() {
|
||||
@Override
|
||||
protected SearchEngine doInBackground(Void... params) {
|
||||
String identifier = GeckoSharedPrefs.forApp(context).getString(Constants.PREF_SEARCH_ENGINE_KEY, null);
|
||||
if (!TextUtils.isEmpty(identifier)) {
|
||||
try {
|
||||
return createEngine(identifier);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(LOG_TAG, "Exception creating search engine from pref. Falling back to default engine.", e);
|
||||
public void run() {
|
||||
// First look for a default name stored in shared preferences.
|
||||
String name = GeckoSharedPrefs.forApp(context).getString(PREF_DEFAULT_ENGINE_KEY, null);
|
||||
|
||||
if (name != null) {
|
||||
Log.d(LOG_TAG, "Found default engine name in SharedPreferences: " + name);
|
||||
} else {
|
||||
// First, look for the default search engine in a distribution.
|
||||
name = getDefaultEngineNameFromDistribution();
|
||||
if (name == null) {
|
||||
// Otherwise, get the default engine that we ship.
|
||||
name = getDefaultEngineNameFromLocale();
|
||||
}
|
||||
|
||||
// Store the default engine name for the future.
|
||||
// Increment an 'ignore' counter so that this preference change
|
||||
// won'tcause getDefaultEngine to be called again.
|
||||
ignorePreferenceChange++;
|
||||
GeckoSharedPrefs.forApp(context)
|
||||
.edit()
|
||||
.putString(PREF_DEFAULT_ENGINE_KEY, name)
|
||||
.apply();
|
||||
}
|
||||
|
||||
try {
|
||||
return createEngine(Constants.DEFAULT_ENGINE_IDENTIFIER);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(LOG_TAG, "Exception creating search engine from default identifier. " +
|
||||
"This will happen if the locale doesn't contain the default search plugin.", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
final SearchEngine engine = createEngineFromName(name);
|
||||
runCallback(engine, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(SearchEngine engine) {
|
||||
if (engine != null) {
|
||||
// Only touch engine on the main thread.
|
||||
SearchEngineManager.this.engine = engine;
|
||||
if (callback != null) {
|
||||
callback.execute(engine);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
task.execute();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a list of SearchEngine instances from all available open search plugins.
|
||||
* This method does disk I/O, call it from a background thread.
|
||||
* Looks for a default search engine included in a distribution.
|
||||
* This method must be called after the distribution is ready.
|
||||
*
|
||||
* @return List of SearchEngine instances
|
||||
* @return search engine name.
|
||||
*/
|
||||
public List<SearchEngine> getAllEngines() {
|
||||
// First try to read the engine list from the jar.
|
||||
InputStream in = getInputStreamFromJar("list.txt");
|
||||
private String getDefaultEngineNameFromDistribution() {
|
||||
if (!distribution.exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<SearchEngine> list = new ArrayList<SearchEngine>();
|
||||
final File prefFile = distribution.getDistributionFile("preferences.json");
|
||||
if (prefFile == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
final JSONObject all = new JSONObject(FileUtils.getFileContents(prefFile));
|
||||
|
||||
// First, check to see if there's a locale-specific override.
|
||||
final String languageTag = BrowserLocaleManager.getLanguageTag(Locale.getDefault());
|
||||
final String overridesKey = "LocalizablePreferences." + languageTag;
|
||||
if (all.has(overridesKey)) {
|
||||
final JSONObject overridePrefs = all.getJSONObject(overridesKey);
|
||||
if (overridePrefs.has(PREF_GECKO_DEFAULT_ENGINE)) {
|
||||
Log.d(LOG_TAG, "Found default engine name in distribution LocalizablePreferences override.");
|
||||
return overridePrefs.getString(PREF_GECKO_DEFAULT_ENGINE);
|
||||
}
|
||||
}
|
||||
|
||||
// Next, check to see if there's a non-override default pref.
|
||||
if (all.has("LocalizablePreferences")) {
|
||||
final JSONObject localizablePrefs = all.getJSONObject("LocalizablePreferences");
|
||||
if (localizablePrefs.has(PREF_GECKO_DEFAULT_ENGINE)) {
|
||||
Log.d(LOG_TAG, "Found default engine name in distribution LocalizablePreferences.");
|
||||
return localizablePrefs.getString(PREF_GECKO_DEFAULT_ENGINE);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(LOG_TAG, "Error getting search engine name from preferences.json", e);
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOG_TAG, "Error parsing preferences.json", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for the default search engine shipped in the locale.
|
||||
*
|
||||
* @return search engine name.
|
||||
*/
|
||||
private String getDefaultEngineNameFromLocale() {
|
||||
try {
|
||||
final JSONObject browsersearch = new JSONObject(RawResource.getAsString(context, R.raw.browsersearch));
|
||||
if (browsersearch.has("default")) {
|
||||
Log.d(LOG_TAG, "Found default engine name in browsersearch.json.");
|
||||
return browsersearch.getString("default");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(LOG_TAG, "Error getting search engine name from browsersearch.json", e);
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOG_TAG, "Error parsing browsersearch.json", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SearchEngine instance from an engine name.
|
||||
*
|
||||
* To create the engine, we first try to find the search plugin in the distribution
|
||||
* (if one exists), followed by the localized plugins we ship with the browser, and
|
||||
* then finally third-party plugins that are installed in the profile directory.
|
||||
*
|
||||
* This method must be called after the distribution is ready.
|
||||
*
|
||||
* @param name The search engine name (e.g. "Google" or "Amazon.com")
|
||||
* @return SearchEngine instance for name.
|
||||
*/
|
||||
private SearchEngine createEngineFromName(String name) {
|
||||
// First, look in the distribution.
|
||||
SearchEngine engine = createEngineFromDistribution(name);
|
||||
|
||||
// Second, look in the jar for plugins shipped with the locale.
|
||||
if (engine == null) {
|
||||
engine = createEngineFromLocale(name);
|
||||
}
|
||||
|
||||
// Finally, look in the profile for third-party plugins.
|
||||
if (engine == null) {
|
||||
engine = createEngineFromProfile(name);
|
||||
}
|
||||
|
||||
if (engine == null) {
|
||||
Log.e(LOG_TAG, "Could not create search engine from name: " + name);
|
||||
}
|
||||
|
||||
return engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SearchEngine instance for a distribution search plugin.
|
||||
*
|
||||
* This method iterates through the distribution searchplugins directory,
|
||||
* creating SearchEngine instances until it finds one with the right name.
|
||||
*
|
||||
* This method must be called after the distribution is ready.
|
||||
*
|
||||
* @param name Search engine name.
|
||||
* @return SearchEngine instance for name.
|
||||
*/
|
||||
private SearchEngine createEngineFromDistribution(String name) {
|
||||
if (!distribution.exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final File pluginsDir = distribution.getDistributionFile("searchplugins");
|
||||
if (pluginsDir == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final File[] files = (new File(pluginsDir, "common")).listFiles();
|
||||
return createEngineFromFileList(files, 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
|
||||
* 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");
|
||||
InputStreamReader isr = null;
|
||||
|
||||
try {
|
||||
|
@ -141,10 +312,14 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
|
|||
BufferedReader br = new BufferedReader(isr);
|
||||
String identifier;
|
||||
while ((identifier = br.readLine()) != null) {
|
||||
list.add(createEngine(identifier));
|
||||
final InputStream pluginIn = getInputStreamFromSearchPluginsJar(identifier + ".xml");
|
||||
final SearchEngine engine = createEngineFromInputStream(identifier, pluginIn);
|
||||
if (engine != null && engine.getName().equals(name)) {
|
||||
return engine;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Error creating all search engines from list.txt");
|
||||
Log.e(LOG_TAG, "Error creating shipped search engine from name: " + name, e);
|
||||
} finally {
|
||||
if (isr != null) {
|
||||
try {
|
||||
|
@ -159,27 +334,62 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
|
|||
// Ignore.
|
||||
}
|
||||
}
|
||||
return list;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SearchEngine instance from an open search plugin.
|
||||
* This method does disk I/O, call it from a background thread.
|
||||
* Creates a SearchEngine instance for a search plugin in the profile directory.
|
||||
*
|
||||
* @param identifier search engine identifier (e.g. "google")
|
||||
* @return SearchEngine instance for identifier
|
||||
* This method iterates through the profile searchplugins directory, creating
|
||||
* SearchEngine instances until it finds one with the right name.
|
||||
*
|
||||
* @param name Search engine name.
|
||||
* @return SearchEngine instance for name.
|
||||
*/
|
||||
private SearchEngine createEngine(String identifier) {
|
||||
InputStream in = getInputStreamFromJar(identifier + ".xml");
|
||||
|
||||
if (in == null) {
|
||||
in = getEngineFromProfile(identifier);
|
||||
private SearchEngine createEngineFromProfile(String name) {
|
||||
final File pluginsDir = GeckoProfile.get(context).getFile("searchplugins");
|
||||
if (pluginsDir == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (in == null) {
|
||||
throw new IllegalArgumentException("Couldn't find search engine for identifier: " + identifier);
|
||||
}
|
||||
final File[] files = pluginsDir.listFiles();
|
||||
return createEngineFromFileList(files, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method iterates through an array of search plugin files, creating
|
||||
* SearchEngine instances until it finds one with the right name.
|
||||
*
|
||||
* @param files Array of search plugin files.
|
||||
* @param name Search engine name.
|
||||
* @return SearchEngine instance for name.
|
||||
*/
|
||||
private SearchEngine createEngineFromFileList(File[] files, String name) {
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
try {
|
||||
final FileInputStream fis = new FileInputStream(files[i]);
|
||||
final SearchEngine engine = createEngineFromInputStream(null, fis);
|
||||
if (engine != null && engine.getName().equals(name)) {
|
||||
return engine;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(LOG_TAG, "Error creating earch engine from name: " + name, e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SearchEngine instance from an InputStream.
|
||||
*
|
||||
* This method closes the stream after it is done reading it.
|
||||
*
|
||||
* @param identifier Seach engine identifier. This only exists for search engines that
|
||||
* ship with the default set of engines in the locale.
|
||||
* @param in InputStream for search plugin XML file.
|
||||
* @return SearchEngine instance.
|
||||
*/
|
||||
private SearchEngine createEngineFromInputStream(String identifier, InputStream in) {
|
||||
try {
|
||||
try {
|
||||
return new SearchEngine(identifier, in);
|
||||
|
@ -194,13 +404,12 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
|
|||
}
|
||||
|
||||
/**
|
||||
* Reads a file from the searchplugins directory in the Gecko jar. This will only work
|
||||
* if the search activity is built as part of mozilla-central.
|
||||
* Reads a file from the searchplugins directory in the Gecko jar.
|
||||
*
|
||||
* @param fileName name of the file to read
|
||||
* @return InputStream for file
|
||||
* @param fileName name of the file to read.
|
||||
* @return InputStream for file.
|
||||
*/
|
||||
private InputStream getInputStreamFromJar(String fileName) {
|
||||
private InputStream getInputStreamFromSearchPluginsJar(String fileName) {
|
||||
final Locale locale = Locale.getDefault();
|
||||
|
||||
// First, try a file path for the full locale.
|
||||
|
@ -228,32 +437,14 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the jar URL for a file in the searchplugins directory
|
||||
* Gets the jar URL for a file in the searchplugins directory.
|
||||
*
|
||||
* @param locale String representing the Gecko locale (e.g. "en-US")
|
||||
* @param fileName name of the file to read
|
||||
* @return URL for jar file
|
||||
* @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 String getSearchPluginsJarURL(String locale, String fileName) {
|
||||
final String path = "!/chrome/" + locale + "/locale/" + locale + "/browser/searchplugins/" + fileName;
|
||||
return "jar:jar:file://" + context.getPackageResourcePath() + "!/" + AppConstants.OMNIJAR_NAME + path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the search plugin XML file from the searchplugins directory in the Gecko profile.
|
||||
*
|
||||
* @param identifier
|
||||
* @return InputStream for search plugin file
|
||||
*/
|
||||
private InputStream getEngineFromProfile(String identifier) {
|
||||
final File f = GeckoProfile.get(context).getFile("searchplugins/" + identifier + ".xml");
|
||||
if (f.exists()) {
|
||||
try {
|
||||
return new FileInputStream(f);
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(LOG_TAG, "Exception getting search engine from profile", e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче