mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 958192 - Use gecko messages to request current set of available panels from JS. r=lucasr
This commit is contained in:
parent
2dae43534f
commit
80b44e380a
@ -6,7 +6,9 @@
|
||||
package org.mozilla.gecko.home;
|
||||
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoEvent;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
@ -19,7 +21,11 @@ import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class PanelManager implements GeckoEventListener {
|
||||
private static final String LOGTAG = "GeckoPanelManager";
|
||||
@ -34,54 +40,73 @@ public class PanelManager implements GeckoEventListener {
|
||||
}
|
||||
}
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
public PanelManager(Context context) {
|
||||
mContext = context;
|
||||
|
||||
// Add a listener to handle any new panels that are added after the panels have been loaded.
|
||||
GeckoAppShell.getEventDispatcher().registerEventListener("HomePanels:Added", this);
|
||||
public interface RequestCallback {
|
||||
public void onComplete(List<PanelInfo> panelInfos);
|
||||
}
|
||||
|
||||
private static AtomicInteger sRequestId = new AtomicInteger(0);
|
||||
|
||||
// Stores set of pending request callbacks.
|
||||
private static final Map<Integer, RequestCallback> sCallbacks = Collections.synchronizedMap(new HashMap<Integer, RequestCallback>());
|
||||
|
||||
/**
|
||||
* Reads list info from SharedPreferences. Don't call this on the main thread!
|
||||
* Asynchronously fetches list of available panels from Gecko.
|
||||
*
|
||||
* @return List<PanelInfo> A list of PanelInfos for each registered list.
|
||||
* @param callback onComplete will be called on the UI thread.
|
||||
*/
|
||||
public List<PanelInfo> getPanelInfos() {
|
||||
final ArrayList<PanelInfo> panelInfos = new ArrayList<PanelInfo>();
|
||||
public void requestAvailablePanels(RequestCallback callback) {
|
||||
final int requestId = sRequestId.getAndIncrement();
|
||||
|
||||
// XXX: We need to use PreferenceManager right now because that's what SharedPreferences.jsm uses (see bug 940575)
|
||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
final String prefValue = prefs.getString("home_lists", "");
|
||||
|
||||
if (!TextUtils.isEmpty(prefValue)) {
|
||||
try {
|
||||
final JSONArray lists = new JSONArray(prefValue);
|
||||
for (int i = 0; i < lists.length(); i++) {
|
||||
final JSONObject list = lists.getJSONObject(i);
|
||||
final PanelInfo info = new PanelInfo(list.getString("id"), list.getString("title"));
|
||||
panelInfos.add(info);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "Exception getting list info", e);
|
||||
synchronized(sCallbacks) {
|
||||
// If there are no pending callbacks, register the event listener.
|
||||
if (sCallbacks.isEmpty()) {
|
||||
GeckoAppShell.getEventDispatcher().registerEventListener("HomePanels:Data", this);
|
||||
}
|
||||
sCallbacks.put(requestId, callback);
|
||||
}
|
||||
return panelInfos;
|
||||
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("HomePanels:Get", Integer.toString(requestId)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for "HomePanels:Added"
|
||||
* Handles "HomePanels:Data" events.
|
||||
*/
|
||||
@Override
|
||||
public void handleMessage(String event, JSONObject message) {
|
||||
final ArrayList<PanelInfo> panelInfos = new ArrayList<PanelInfo>();
|
||||
|
||||
try {
|
||||
final PanelInfo info = new PanelInfo(message.getString("id"), message.getString("title"));
|
||||
final JSONArray panels = message.getJSONArray("panels");
|
||||
final int count = panels.length();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final PanelInfo panelInfo = getPanelInfoFromJSON(panels.getJSONObject(i));
|
||||
panelInfos.add(panelInfo);
|
||||
}
|
||||
|
||||
// Do something to update the set of list pages.
|
||||
final RequestCallback callback;
|
||||
final int requestId = message.getInt("requestId");
|
||||
|
||||
synchronized(sCallbacks) {
|
||||
callback = sCallbacks.remove(requestId);
|
||||
|
||||
// Unregister the event listener if there are no more pending callbacks.
|
||||
if (sCallbacks.isEmpty()) {
|
||||
GeckoAppShell.getEventDispatcher().unregisterEventListener("HomePanels:Data", this);
|
||||
}
|
||||
}
|
||||
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
callback.onComplete(panelInfos);
|
||||
}
|
||||
});
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "Exception handling " + event + " message", e);
|
||||
}
|
||||
}
|
||||
|
||||
private PanelInfo getPanelInfoFromJSON(JSONObject jsonPanelInfo) throws JSONException {
|
||||
return new PanelInfo(jsonPanelInfo.getString("id"), jsonPanelInfo.getString("title"));
|
||||
}
|
||||
}
|
||||
|
@ -134,6 +134,22 @@ var LazyNotificationGetter = {
|
||||
});
|
||||
});
|
||||
|
||||
// Lazily-loaded JS modules that use observer notifications
|
||||
[
|
||||
["Home", ["HomePanels:Get"], "resource://gre/modules/Home.jsm"],
|
||||
].forEach(module => {
|
||||
let [name, notifications, resource] = module;
|
||||
XPCOMUtils.defineLazyModuleGetter(this, name, resource);
|
||||
notifications.forEach(notification => {
|
||||
let o = {
|
||||
notification: notification,
|
||||
observe: (s, t, d) => this[name].observe(s, t, d)
|
||||
};
|
||||
Services.obs.addObserver(o, notification, false);
|
||||
LazyNotificationGetter.observers.push(o);
|
||||
});
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "Haptic",
|
||||
"@mozilla.org/widget/hapticfeedback;1", "nsIHapticFeedback");
|
||||
|
||||
|
@ -145,25 +145,27 @@ function Panel(options) {
|
||||
this.title = options.title;
|
||||
}
|
||||
|
||||
function HomePanels() {
|
||||
// XXX: Not renaming this because it is going away in bug 958192
|
||||
this.PREF_KEY = "home_lists";
|
||||
let HomePanels = {
|
||||
// Holds the currrent set of registered panels.
|
||||
_panels: {},
|
||||
|
||||
this._sharedPrefs = new SharedPreferences();
|
||||
this._panels = {};
|
||||
_handleGet: function(requestId) {
|
||||
let panels = [];
|
||||
for (let id in this._panels) {
|
||||
let panel = this._panels[id];
|
||||
panels.push({
|
||||
id: panel.id,
|
||||
title: panel.title
|
||||
});
|
||||
}
|
||||
|
||||
let prefValue = this._sharedPrefs.getCharPref(this.PREF_KEY);
|
||||
if (!prefValue) {
|
||||
return;
|
||||
}
|
||||
sendMessageToJava({
|
||||
type: "HomePanels:Data",
|
||||
panels: panels,
|
||||
requestId: requestId
|
||||
});
|
||||
},
|
||||
|
||||
JSON.parse(prefValue).forEach(data => {
|
||||
let panel = new Panel(data);
|
||||
this._panels[panel.id] = panel;
|
||||
});
|
||||
}
|
||||
|
||||
HomePanels.prototype = {
|
||||
add: function(options) {
|
||||
let panel = new Panel(options);
|
||||
if (!panel.id || !panel.title) {
|
||||
@ -176,35 +178,29 @@ HomePanels.prototype = {
|
||||
}
|
||||
|
||||
this._panels[panel.id] = panel;
|
||||
this._updateSharedPref();
|
||||
|
||||
// Send a message to Java to update the home pager if it's currently showing
|
||||
sendMessageToJava({
|
||||
type: "HomePanels:Added",
|
||||
id: panel.id,
|
||||
title: panel.title
|
||||
});
|
||||
},
|
||||
|
||||
remove: function(id) {
|
||||
delete this._panels[id];
|
||||
this._updateSharedPref();
|
||||
},
|
||||
|
||||
// Set a shared pref so that Java can know about this panel before Gecko is running
|
||||
_updateSharedPref: function() {
|
||||
let panels = [];
|
||||
for (let id in this._panels) {
|
||||
let panel = this._panels[id];
|
||||
panels.push({ id: panel.id, title: panel.title});
|
||||
}
|
||||
this._sharedPrefs.setCharPref(this.PREF_KEY, JSON.stringify(panels));
|
||||
sendMessageToJava({
|
||||
type: "HomePanels:Remove",
|
||||
id: panel.id
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Public API
|
||||
this.Home = {
|
||||
banner: HomeBanner,
|
||||
panels: new HomePanels()
|
||||
panels: HomePanels,
|
||||
|
||||
// Lazy notification observer registered in browser.js
|
||||
observe: function(subject, topic, data) {
|
||||
switch(topic) {
|
||||
case "HomePanels:Get":
|
||||
HomePanels._handleGet(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user