Bug 1065891 - (Part 2) Update the search activity default engine when the gecko default search engine changes. r=bnicholson

This commit is contained in:
Margaret Leibovic 2014-09-29 20:56:20 -07:00
Родитель fdc376a084
Коммит 389e436044
2 изменённых файлов: 71 добавлений и 1 удалений

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

@ -98,6 +98,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "NetErrorHelper",
XPCOMUtils.defineLazyModuleGetter(this, "PermissionsUtils", XPCOMUtils.defineLazyModuleGetter(this, "PermissionsUtils",
"resource://gre/modules/PermissionsUtils.jsm"); "resource://gre/modules/PermissionsUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "SharedPreferences",
"resource://gre/modules/SharedPreferences.jsm");
// Lazily-loaded browser scripts: // Lazily-loaded browser scripts:
[ [
["SelectHelper", "chrome://browser/content/SelectHelper.js"], ["SelectHelper", "chrome://browser/content/SelectHelper.js"],
@ -6764,12 +6767,16 @@ var SearchEngines = {
PREF_SUGGEST_ENABLED: "browser.search.suggest.enabled", PREF_SUGGEST_ENABLED: "browser.search.suggest.enabled",
PREF_SUGGEST_PROMPTED: "browser.search.suggest.prompted", PREF_SUGGEST_PROMPTED: "browser.search.suggest.prompted",
// Shared preference key used for search activity default engine.
PREF_SEARCH_ACTIVITY_ENGINE_KEY: "search.engines.default",
init: function init() { init: function init() {
Services.obs.addObserver(this, "SearchEngines:Add", false); Services.obs.addObserver(this, "SearchEngines:Add", false);
Services.obs.addObserver(this, "SearchEngines:GetVisible", false); Services.obs.addObserver(this, "SearchEngines:GetVisible", false);
Services.obs.addObserver(this, "SearchEngines:Remove", false); Services.obs.addObserver(this, "SearchEngines:Remove", false);
Services.obs.addObserver(this, "SearchEngines:RestoreDefaults", false); Services.obs.addObserver(this, "SearchEngines:RestoreDefaults", false);
Services.obs.addObserver(this, "SearchEngines:SetDefault", false); Services.obs.addObserver(this, "SearchEngines:SetDefault", false);
Services.obs.addObserver(this, "browser-search-engine-modified", false);
let filter = { let filter = {
matches: function (aElement) { matches: function (aElement) {
@ -6814,6 +6821,7 @@ var SearchEngines = {
Services.obs.removeObserver(this, "SearchEngines:Remove"); Services.obs.removeObserver(this, "SearchEngines:Remove");
Services.obs.removeObserver(this, "SearchEngines:RestoreDefaults"); Services.obs.removeObserver(this, "SearchEngines:RestoreDefaults");
Services.obs.removeObserver(this, "SearchEngines:SetDefault"); Services.obs.removeObserver(this, "SearchEngines:SetDefault");
Services.obs.removeObserver(this, "browser-search-engine-modified");
if (this._contextMenuId != null) if (this._contextMenuId != null)
NativeWindow.contextmenus.remove(this._contextMenuId); NativeWindow.contextmenus.remove(this._contextMenuId);
}, },
@ -6894,13 +6902,49 @@ var SearchEngines = {
Services.search.moveEngine(engine, 0); Services.search.moveEngine(engine, 0);
Services.search.defaultEngine = engine; Services.search.defaultEngine = engine;
break; break;
case "browser-search-engine-modified":
if (aData == "engine-default") {
this._setSearchActivityDefaultPref(aSubject.QueryInterface(Ci.nsISearchEngine));
}
break;
default: default:
dump("Unexpected message type observed: " + aTopic); dump("Unexpected message type observed: " + aTopic);
break; break;
} }
}, },
// 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);
},
// Display context menu listing names of the search engines available to be added. // Display context menu listing names of the search engines available to be added.
displaySearchEnginesList: function displaySearchEnginesList(aData) { displaySearchEnginesList: function displaySearchEnginesList(aData) {
let data = JSON.parse(aData); let data = JSON.parse(aData);

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

@ -12,12 +12,16 @@ import android.util.Log;
import org.mozilla.gecko.AppConstants; import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.BrowserLocaleManager; import org.mozilla.gecko.BrowserLocaleManager;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.GeckoSharedPrefs; import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.util.GeckoJarReader; import org.mozilla.gecko.util.GeckoJarReader;
import org.mozilla.search.Constants; import org.mozilla.search.Constants;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -177,6 +181,10 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
private SearchEngine createEngine(String identifier) { private SearchEngine createEngine(String identifier) {
InputStream in = getInputStreamFromJar(identifier + ".xml"); InputStream in = getInputStreamFromJar(identifier + ".xml");
if (in == null) {
in = getEngineFromProfile(identifier);
}
// Fallback for standalone search activity. // Fallback for standalone search activity.
if (in == null) { if (in == null) {
in = getEngineFromAssets(identifier); in = getEngineFromAssets(identifier);
@ -262,4 +270,22 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
final String path = "!/chrome/" + locale + "/locale/" + locale + "/browser/searchplugins/" + fileName; final String path = "!/chrome/" + locale + "/locale/" + locale + "/browser/searchplugins/" + fileName;
return "jar:jar:file://" + context.getPackageResourcePath() + "!/" + AppConstants.OMNIJAR_NAME + path; 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;
}
} }