|
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/. */ |
|
5 |
|
6 package org.mozilla.gecko.home; |
|
7 |
|
8 import java.util.ArrayList; |
|
9 import java.util.List; |
|
10 import java.util.Set; |
|
11 import java.util.concurrent.atomic.AtomicInteger; |
|
12 |
|
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; |
|
21 |
|
22 import android.util.Log; |
|
23 import android.util.SparseArray; |
|
24 |
|
25 public class PanelInfoManager implements GeckoEventListener { |
|
26 private static final String LOGTAG = "GeckoPanelInfoManager"; |
|
27 |
|
28 public class PanelInfo { |
|
29 private final String mId; |
|
30 private final String mTitle; |
|
31 private final JSONObject mJSONData; |
|
32 |
|
33 public PanelInfo(String id, String title, JSONObject jsonData) { |
|
34 mId = id; |
|
35 mTitle = title; |
|
36 mJSONData = jsonData; |
|
37 } |
|
38 |
|
39 public String getId() { |
|
40 return mId; |
|
41 } |
|
42 |
|
43 public String getTitle() { |
|
44 return mTitle; |
|
45 } |
|
46 |
|
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 } |
|
56 |
|
57 public interface RequestCallback { |
|
58 public void onComplete(List<PanelInfo> panelInfos); |
|
59 } |
|
60 |
|
61 private static AtomicInteger sRequestId = new AtomicInteger(0); |
|
62 |
|
63 // Stores set of pending request callbacks. |
|
64 private static final SparseArray<RequestCallback> sCallbacks = new SparseArray<RequestCallback>(); |
|
65 |
|
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(); |
|
76 |
|
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 } |
|
84 |
|
85 final JSONObject message = new JSONObject(); |
|
86 try { |
|
87 message.put("requestId", requestId); |
|
88 |
|
89 if (ids != null && ids.size() > 0) { |
|
90 JSONArray idsArray = new JSONArray(); |
|
91 for (String id : ids) { |
|
92 idsArray.put(id); |
|
93 } |
|
94 |
|
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 } |
|
101 |
|
102 GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("HomePanels:Get", message.toString())); |
|
103 } |
|
104 |
|
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 } |
|
113 |
|
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>(); |
|
120 |
|
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 } |
|
128 |
|
129 final RequestCallback callback; |
|
130 final int requestId = message.getInt("requestId"); |
|
131 |
|
132 synchronized(sCallbacks) { |
|
133 callback = sCallbacks.get(requestId); |
|
134 sCallbacks.delete(requestId); |
|
135 |
|
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 } |
|
141 |
|
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 } |
|
152 |
|
153 private PanelInfo getPanelInfoFromJSON(JSONObject jsonPanelInfo) throws JSONException { |
|
154 final String id = jsonPanelInfo.getString("id"); |
|
155 final String title = jsonPanelInfo.getString("title"); |
|
156 |
|
157 return new PanelInfo(id, title, jsonPanelInfo); |
|
158 } |
|
159 } |