1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/home/PanelInfoManager.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,159 @@ 1.4 +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +package org.mozilla.gecko.home; 1.10 + 1.11 +import java.util.ArrayList; 1.12 +import java.util.List; 1.13 +import java.util.Set; 1.14 +import java.util.concurrent.atomic.AtomicInteger; 1.15 + 1.16 +import org.json.JSONArray; 1.17 +import org.json.JSONException; 1.18 +import org.json.JSONObject; 1.19 +import org.mozilla.gecko.GeckoAppShell; 1.20 +import org.mozilla.gecko.GeckoEvent; 1.21 +import org.mozilla.gecko.home.HomeConfig.PanelConfig; 1.22 +import org.mozilla.gecko.util.GeckoEventListener; 1.23 +import org.mozilla.gecko.util.ThreadUtils; 1.24 + 1.25 +import android.util.Log; 1.26 +import android.util.SparseArray; 1.27 + 1.28 +public class PanelInfoManager implements GeckoEventListener { 1.29 + private static final String LOGTAG = "GeckoPanelInfoManager"; 1.30 + 1.31 + public class PanelInfo { 1.32 + private final String mId; 1.33 + private final String mTitle; 1.34 + private final JSONObject mJSONData; 1.35 + 1.36 + public PanelInfo(String id, String title, JSONObject jsonData) { 1.37 + mId = id; 1.38 + mTitle = title; 1.39 + mJSONData = jsonData; 1.40 + } 1.41 + 1.42 + public String getId() { 1.43 + return mId; 1.44 + } 1.45 + 1.46 + public String getTitle() { 1.47 + return mTitle; 1.48 + } 1.49 + 1.50 + public PanelConfig toPanelConfig() { 1.51 + try { 1.52 + return new PanelConfig(mJSONData); 1.53 + } catch (Exception e) { 1.54 + Log.e(LOGTAG, "Failed to convert PanelInfo to PanelConfig", e); 1.55 + return null; 1.56 + } 1.57 + } 1.58 + } 1.59 + 1.60 + public interface RequestCallback { 1.61 + public void onComplete(List<PanelInfo> panelInfos); 1.62 + } 1.63 + 1.64 + private static AtomicInteger sRequestId = new AtomicInteger(0); 1.65 + 1.66 + // Stores set of pending request callbacks. 1.67 + private static final SparseArray<RequestCallback> sCallbacks = new SparseArray<RequestCallback>(); 1.68 + 1.69 + /** 1.70 + * Asynchronously fetches list of available panels from Gecko 1.71 + * for the given IDs. 1.72 + * 1.73 + * @param ids list of panel ids to be fetched. A null value will fetch all 1.74 + * available panels. 1.75 + * @param callback onComplete will be called on the UI thread. 1.76 + */ 1.77 + public void requestPanelsById(Set<String> ids, RequestCallback callback) { 1.78 + final int requestId = sRequestId.getAndIncrement(); 1.79 + 1.80 + synchronized(sCallbacks) { 1.81 + // If there are no pending callbacks, register the event listener. 1.82 + if (sCallbacks.size() == 0) { 1.83 + GeckoAppShell.getEventDispatcher().registerEventListener("HomePanels:Data", this); 1.84 + } 1.85 + sCallbacks.put(requestId, callback); 1.86 + } 1.87 + 1.88 + final JSONObject message = new JSONObject(); 1.89 + try { 1.90 + message.put("requestId", requestId); 1.91 + 1.92 + if (ids != null && ids.size() > 0) { 1.93 + JSONArray idsArray = new JSONArray(); 1.94 + for (String id : ids) { 1.95 + idsArray.put(id); 1.96 + } 1.97 + 1.98 + message.put("ids", idsArray); 1.99 + } 1.100 + } catch (JSONException e) { 1.101 + Log.e(LOGTAG, "Failed to build event to request panels by id", e); 1.102 + return; 1.103 + } 1.104 + 1.105 + GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("HomePanels:Get", message.toString())); 1.106 + } 1.107 + 1.108 + /** 1.109 + * Asynchronously fetches list of available panels from Gecko. 1.110 + * 1.111 + * @param callback onComplete will be called on the UI thread. 1.112 + */ 1.113 + public void requestAvailablePanels(RequestCallback callback) { 1.114 + requestPanelsById(null, callback); 1.115 + } 1.116 + 1.117 + /** 1.118 + * Handles "HomePanels:Data" events. 1.119 + */ 1.120 + @Override 1.121 + public void handleMessage(String event, JSONObject message) { 1.122 + final ArrayList<PanelInfo> panelInfos = new ArrayList<PanelInfo>(); 1.123 + 1.124 + try { 1.125 + final JSONArray panels = message.getJSONArray("panels"); 1.126 + final int count = panels.length(); 1.127 + for (int i = 0; i < count; i++) { 1.128 + final PanelInfo panelInfo = getPanelInfoFromJSON(panels.getJSONObject(i)); 1.129 + panelInfos.add(panelInfo); 1.130 + } 1.131 + 1.132 + final RequestCallback callback; 1.133 + final int requestId = message.getInt("requestId"); 1.134 + 1.135 + synchronized(sCallbacks) { 1.136 + callback = sCallbacks.get(requestId); 1.137 + sCallbacks.delete(requestId); 1.138 + 1.139 + // Unregister the event listener if there are no more pending callbacks. 1.140 + if (sCallbacks.size() == 0) { 1.141 + GeckoAppShell.getEventDispatcher().unregisterEventListener("HomePanels:Data", this); 1.142 + } 1.143 + } 1.144 + 1.145 + ThreadUtils.postToUiThread(new Runnable() { 1.146 + @Override 1.147 + public void run() { 1.148 + callback.onComplete(panelInfos); 1.149 + } 1.150 + }); 1.151 + } catch (JSONException e) { 1.152 + Log.e(LOGTAG, "Exception handling " + event + " message", e); 1.153 + } 1.154 + } 1.155 + 1.156 + private PanelInfo getPanelInfoFromJSON(JSONObject jsonPanelInfo) throws JSONException { 1.157 + final String id = jsonPanelInfo.getString("id"); 1.158 + final String title = jsonPanelInfo.getString("title"); 1.159 + 1.160 + return new PanelInfo(id, title, jsonPanelInfo); 1.161 + } 1.162 +}