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