mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-06 00:10:25 +00:00
Bug 978991 - Add hooks to let an add-on know when a panel is installed/uninstalled. r=liuche
This commit is contained in:
parent
abe5440530
commit
6082f66aa9
@ -5,6 +5,8 @@
|
||||
|
||||
package org.mozilla.gecko.home;
|
||||
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoEvent;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
@ -926,6 +928,7 @@ public final class HomeConfig {
|
||||
private final HomeConfig mHomeConfig;
|
||||
private final Map<String, PanelConfig> mConfigMap;
|
||||
private final List<String> mConfigOrder;
|
||||
private final List<GeckoEvent> mEventQueue;
|
||||
private final Thread mOriginalThread;
|
||||
|
||||
private PanelConfig mDefaultPanel;
|
||||
@ -939,6 +942,7 @@ public final class HomeConfig {
|
||||
mOriginalThread = Thread.currentThread();
|
||||
mConfigMap = new HashMap<String, PanelConfig>();
|
||||
mConfigOrder = new LinkedList<String>();
|
||||
mEventQueue = new LinkedList<GeckoEvent>();
|
||||
mEnabledCount = 0;
|
||||
|
||||
mHasChanged = false;
|
||||
@ -1144,6 +1148,9 @@ public final class HomeConfig {
|
||||
}
|
||||
|
||||
installed = true;
|
||||
|
||||
// Add an event to the queue if a new panel is sucessfully installed.
|
||||
mEventQueue.add(GeckoEvent.createBroadcastEvent("HomePanels:Installed", panelConfig.getId()));
|
||||
}
|
||||
|
||||
mHasChanged = true;
|
||||
@ -1178,6 +1185,9 @@ public final class HomeConfig {
|
||||
findNewDefault();
|
||||
}
|
||||
|
||||
// Add an event to the queue if a panel is succesfully uninstalled.
|
||||
mEventQueue.add(GeckoEvent.createBroadcastEvent("HomePanels:Uninstalled", panelId));
|
||||
|
||||
mHasChanged = true;
|
||||
return true;
|
||||
}
|
||||
@ -1246,10 +1256,18 @@ public final class HomeConfig {
|
||||
final State newConfigState =
|
||||
new State(mHomeConfig, makeOrderedCopy(true), isDefault());
|
||||
|
||||
// Copy the event queue to a new list, so that we only modify mEventQueue on
|
||||
// the original thread where it was created.
|
||||
final LinkedList<GeckoEvent> eventQueueCopy = new LinkedList<GeckoEvent>(mEventQueue);
|
||||
mEventQueue.clear();
|
||||
|
||||
ThreadUtils.getBackgroundHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mHomeConfig.save(newConfigState);
|
||||
|
||||
// Send pending events after the new config is saved.
|
||||
sendEventsToGecko(eventQueueCopy);
|
||||
}
|
||||
});
|
||||
|
||||
@ -1272,6 +1290,10 @@ public final class HomeConfig {
|
||||
// need to deep copy the current PanelConfig instances.
|
||||
mHomeConfig.save(newConfigState);
|
||||
|
||||
// Send pending events after the new config is saved.
|
||||
sendEventsToGecko(mEventQueue);
|
||||
mEventQueue.clear();
|
||||
|
||||
return newConfigState;
|
||||
}
|
||||
|
||||
@ -1289,6 +1311,12 @@ public final class HomeConfig {
|
||||
return mConfigMap.isEmpty();
|
||||
}
|
||||
|
||||
private void sendEventsToGecko(List<GeckoEvent> events) {
|
||||
for (GeckoEvent e : events) {
|
||||
GeckoAppShell.sendEventToGecko(e);
|
||||
}
|
||||
}
|
||||
|
||||
private class EditorIterator implements Iterator<PanelConfig> {
|
||||
private final Iterator<String> mOrderIterator;
|
||||
|
||||
|
@ -131,7 +131,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "CharsetMenu",
|
||||
|
||||
// Lazily-loaded JS modules that use observer notifications
|
||||
[
|
||||
["Home", ["HomePanels:Get", "HomePanels:Authenticate"], "resource://gre/modules/Home.jsm"],
|
||||
["Home", ["HomePanels:Get", "HomePanels:Authenticate",
|
||||
"HomePanels:Installed", "HomePanels:Uninstalled"], "resource://gre/modules/Home.jsm"],
|
||||
].forEach(module => {
|
||||
let [name, notifications, resource] = module;
|
||||
XPCOMUtils.defineLazyModuleGetter(this, name, resource);
|
||||
|
@ -157,12 +157,74 @@ let HomeBanner = (function () {
|
||||
});
|
||||
})();
|
||||
|
||||
// We need this function to have access to the HomePanels
|
||||
// We need this object to have access to the HomePanels
|
||||
// private members without leaking it outside Home.jsm.
|
||||
let handlePanelsGet;
|
||||
let handlePanelsAuthenticate;
|
||||
let HomePanelsMessageHandlers;
|
||||
|
||||
let HomePanels = (function () {
|
||||
// Functions used to handle messages sent from Java.
|
||||
HomePanelsMessageHandlers = {
|
||||
|
||||
"HomePanels:Get": function handlePanelsGet(data) {
|
||||
data = JSON.parse(data);
|
||||
|
||||
let requestId = data.requestId;
|
||||
let ids = data.ids || null;
|
||||
|
||||
let panels = [];
|
||||
for (let id in _registeredPanels) {
|
||||
// Null ids means we want to fetch all available panels
|
||||
if (ids == null || ids.indexOf(id) >= 0) {
|
||||
try {
|
||||
panels.push(_generatePanel(id));
|
||||
} catch(e) {
|
||||
Cu.reportError("Home.panels: Invalid options, panel.id = " + id + ": " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendMessageToJava({
|
||||
type: "HomePanels:Data",
|
||||
panels: panels,
|
||||
requestId: requestId
|
||||
});
|
||||
},
|
||||
|
||||
"HomePanels:Authenticate": function handlePanelsAuthenticate(id) {
|
||||
// Generate panel options to get auth handler.
|
||||
let options = _registeredPanels[id]();
|
||||
if (!options.authHandler) {
|
||||
throw "Home.panels: Invalid authHandler for panel.id = " + id;
|
||||
}
|
||||
if (!options.authHandler.authenticate || typeof options.authHandler.authenticate !== "function") {
|
||||
throw "Home.panels: Invalid authHandler authenticate function: panel.id = " + this.id;
|
||||
}
|
||||
options.authHandler.authenticate();
|
||||
},
|
||||
|
||||
"HomePanels:Installed": function handlePanelsInstalled(id) {
|
||||
let options = _registeredPanels[id]();
|
||||
if (!options.oninstall) {
|
||||
return;
|
||||
}
|
||||
if (typeof options.oninstall !== "function") {
|
||||
throw "Home.panels: Invalid oninstall function: panel.id = " + this.id;
|
||||
}
|
||||
options.oninstall();
|
||||
},
|
||||
|
||||
"HomePanels:Uninstalled": function handlePanelsUninstalled(id) {
|
||||
let options = _registeredPanels[id]();
|
||||
if (!options.onuninstall) {
|
||||
return;
|
||||
}
|
||||
if (typeof options.onuninstall !== "function") {
|
||||
throw "Home.panels: Invalid onuninstall function: panel.id = " + this.id;
|
||||
}
|
||||
options.onuninstall();
|
||||
}
|
||||
};
|
||||
|
||||
// Holds the current set of registered panels that can be
|
||||
// installed, updated, uninstalled, or unregistered. It maps
|
||||
// panel ids with the functions that dynamically generate
|
||||
@ -265,41 +327,6 @@ let HomePanels = (function () {
|
||||
return new Panel(id, options);
|
||||
};
|
||||
|
||||
handlePanelsGet = function(data) {
|
||||
let requestId = data.requestId;
|
||||
let ids = data.ids || null;
|
||||
|
||||
let panels = [];
|
||||
for (let id in _registeredPanels) {
|
||||
// Null ids means we want to fetch all available panels
|
||||
if (ids == null || ids.indexOf(id) >= 0) {
|
||||
try {
|
||||
panels.push(_generatePanel(id));
|
||||
} catch(e) {
|
||||
Cu.reportError("Home.panels: Invalid options, panel.id = " + id + ": " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendMessageToJava({
|
||||
type: "HomePanels:Data",
|
||||
panels: panels,
|
||||
requestId: requestId
|
||||
});
|
||||
};
|
||||
|
||||
handlePanelsAuthenticate = function(id) {
|
||||
// Generate panel options to get auth handler.
|
||||
let options = _registeredPanels[id]();
|
||||
if (!options.authHandler) {
|
||||
throw "Home.panels: Invalid authHandler for panel.id = " + id;
|
||||
}
|
||||
if (!options.authHandler.authenticate || typeof options.authHandler.authenticate !== "function") {
|
||||
throw "Home.panels: Invalid authHandler authenticate function: panel.id = " + this.id;
|
||||
}
|
||||
options.authHandler.authenticate();
|
||||
};
|
||||
|
||||
// Helper function used to see if a value is in an object.
|
||||
let _valueExists = function(obj, value) {
|
||||
for (let key in obj) {
|
||||
@ -385,13 +412,10 @@ this.Home = Object.freeze({
|
||||
|
||||
// Lazy notification observer registered in browser.js
|
||||
observe: function(subject, topic, data) {
|
||||
switch(topic) {
|
||||
case "HomePanels:Get":
|
||||
handlePanelsGet(JSON.parse(data));
|
||||
break;
|
||||
case "HomePanels:Authenticate":
|
||||
handlePanelsAuthenticate(data);
|
||||
break;
|
||||
if (topic in HomePanelsMessageHandlers) {
|
||||
HomePanelsMessageHandlers[topic](data);
|
||||
} else {
|
||||
Cu.reportError("Home.observe: message handler not found for topic: " + topic);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user