Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 package org.mozilla.gecko.home;
8 import java.util.ArrayList;
9 import java.util.List;
10 import java.util.Set;
11 import java.util.concurrent.atomic.AtomicInteger;
13 import org.json.JSONArray;
14 import org.json.JSONException;
15 import org.json.JSONObject;
16 import org.mozilla.gecko.GeckoAppShell;
17 import org.mozilla.gecko.GeckoEvent;
18 import org.mozilla.gecko.home.HomeConfig.PanelConfig;
19 import org.mozilla.gecko.util.GeckoEventListener;
20 import org.mozilla.gecko.util.ThreadUtils;
22 import android.util.Log;
23 import android.util.SparseArray;
25 public class PanelInfoManager implements GeckoEventListener {
26 private static final String LOGTAG = "GeckoPanelInfoManager";
28 public class PanelInfo {
29 private final String mId;
30 private final String mTitle;
31 private final JSONObject mJSONData;
33 public PanelInfo(String id, String title, JSONObject jsonData) {
34 mId = id;
35 mTitle = title;
36 mJSONData = jsonData;
37 }
39 public String getId() {
40 return mId;
41 }
43 public String getTitle() {
44 return mTitle;
45 }
47 public PanelConfig toPanelConfig() {
48 try {
49 return new PanelConfig(mJSONData);
50 } catch (Exception e) {
51 Log.e(LOGTAG, "Failed to convert PanelInfo to PanelConfig", e);
52 return null;
53 }
54 }
55 }
57 public interface RequestCallback {
58 public void onComplete(List<PanelInfo> panelInfos);
59 }
61 private static AtomicInteger sRequestId = new AtomicInteger(0);
63 // Stores set of pending request callbacks.
64 private static final SparseArray<RequestCallback> sCallbacks = new SparseArray<RequestCallback>();
66 /**
67 * Asynchronously fetches list of available panels from Gecko
68 * for the given IDs.
69 *
70 * @param ids list of panel ids to be fetched. A null value will fetch all
71 * available panels.
72 * @param callback onComplete will be called on the UI thread.
73 */
74 public void requestPanelsById(Set<String> ids, RequestCallback callback) {
75 final int requestId = sRequestId.getAndIncrement();
77 synchronized(sCallbacks) {
78 // If there are no pending callbacks, register the event listener.
79 if (sCallbacks.size() == 0) {
80 GeckoAppShell.getEventDispatcher().registerEventListener("HomePanels:Data", this);
81 }
82 sCallbacks.put(requestId, callback);
83 }
85 final JSONObject message = new JSONObject();
86 try {
87 message.put("requestId", requestId);
89 if (ids != null && ids.size() > 0) {
90 JSONArray idsArray = new JSONArray();
91 for (String id : ids) {
92 idsArray.put(id);
93 }
95 message.put("ids", idsArray);
96 }
97 } catch (JSONException e) {
98 Log.e(LOGTAG, "Failed to build event to request panels by id", e);
99 return;
100 }
102 GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("HomePanels:Get", message.toString()));
103 }
105 /**
106 * Asynchronously fetches list of available panels from Gecko.
107 *
108 * @param callback onComplete will be called on the UI thread.
109 */
110 public void requestAvailablePanels(RequestCallback callback) {
111 requestPanelsById(null, callback);
112 }
114 /**
115 * Handles "HomePanels:Data" events.
116 */
117 @Override
118 public void handleMessage(String event, JSONObject message) {
119 final ArrayList<PanelInfo> panelInfos = new ArrayList<PanelInfo>();
121 try {
122 final JSONArray panels = message.getJSONArray("panels");
123 final int count = panels.length();
124 for (int i = 0; i < count; i++) {
125 final PanelInfo panelInfo = getPanelInfoFromJSON(panels.getJSONObject(i));
126 panelInfos.add(panelInfo);
127 }
129 final RequestCallback callback;
130 final int requestId = message.getInt("requestId");
132 synchronized(sCallbacks) {
133 callback = sCallbacks.get(requestId);
134 sCallbacks.delete(requestId);
136 // Unregister the event listener if there are no more pending callbacks.
137 if (sCallbacks.size() == 0) {
138 GeckoAppShell.getEventDispatcher().unregisterEventListener("HomePanels:Data", this);
139 }
140 }
142 ThreadUtils.postToUiThread(new Runnable() {
143 @Override
144 public void run() {
145 callback.onComplete(panelInfos);
146 }
147 });
148 } catch (JSONException e) {
149 Log.e(LOGTAG, "Exception handling " + event + " message", e);
150 }
151 }
153 private PanelInfo getPanelInfoFromJSON(JSONObject jsonPanelInfo) throws JSONException {
154 final String id = jsonPanelInfo.getString("id");
155 final String title = jsonPanelInfo.getString("title");
157 return new PanelInfo(id, title, jsonPanelInfo);
158 }
159 }