Bug 970707 - Pass refresh to JS callback. r=lucas
authorJosh Dover <gerfuls@gmail.com>
Tue, 15 Apr 2014 15:51:00 +0200
changeset 179197 8956eb0b642e23ef5721dd9d48d9d6758d96a138
parent 179196 a2fb529e5852fa3301903ced3099a5979be32e54
child 179198 c1366bb9277148f8f4e406753a8b425d94b3cfe4
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewerslucas
bugs970707
milestone31.0a1
Bug 970707 - Pass refresh to JS callback. r=lucas
mobile/android/base/home/PanelLayout.java
mobile/android/base/home/PanelRefreshLayout.java
mobile/android/chrome/content/browser.js
mobile/android/modules/Home.jsm
--- a/mobile/android/base/home/PanelLayout.java
+++ b/mobile/android/base/home/PanelLayout.java
@@ -370,17 +370,18 @@ abstract class PanelLayout extends Frame
             panelView.setOnItemOpenListener(new PanelOnItemOpenListener(viewState));
             panelView.setOnKeyListener(new PanelKeyListener(viewState));
 
             if (view instanceof DatasetBacked) {
                 DatasetBacked datasetBacked = (DatasetBacked) view;
                 datasetBacked.setFilterManager(new PanelFilterManager(viewState));
 
                 if (viewConfig.isRefreshEnabled()) {
-                    view = new PanelRefreshLayout(getContext(), view);
+                    view = new PanelRefreshLayout(getContext(), view,
+                                                  mPanelConfig.getId(), viewConfig.getIndex());
                 }
             }
 
             viewState.setView(view);
         }
 
         return view;
     }
--- a/mobile/android/base/home/PanelRefreshLayout.java
+++ b/mobile/android/base/home/PanelRefreshLayout.java
@@ -2,65 +2,94 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.home;
 
 import org.mozilla.gecko.R;
 
+import org.mozilla.gecko.GeckoAppShell;
+import org.mozilla.gecko.GeckoEvent;
 import org.mozilla.gecko.home.PanelLayout.DatasetBacked;
 import org.mozilla.gecko.home.PanelLayout.FilterManager;
 import org.mozilla.gecko.widget.GeckoSwipeRefreshLayout;
 import org.mozilla.gecko.widget.GeckoSwipeRefreshLayout.OnRefreshListener;
 
+import org.json.JSONException;
+import org.json.JSONObject;
+
 import android.content.Context;
 import android.database.Cursor;
+import android.util.Log;
 import android.view.View;
 
 /**
  * Used to wrap a {@code DatasetBacked} ListView or GridView to give the child view swipe-to-refresh
  * capabilities.
  *
  * This view acts as a decorator to forward the {@code DatasetBacked} methods to the child view
  * while providing the refresh gesture support on top of it.
  */
 class PanelRefreshLayout extends GeckoSwipeRefreshLayout implements DatasetBacked {
+    private static final String LOGTAG = "GeckoPanelRefreshLayout";
+
+    private static final String JSON_KEY_PANEL_ID = "panelId";
+    private static final String JSON_KEY_VIEW_INDEX = "viewIndex";
+
+    private final String panelId;
+    private final int viewIndex;
     private final DatasetBacked datasetBacked;
 
     /**
      * @param context Android context.
      * @param childView ListView or GridView. Must implement {@code DatasetBacked}.
+     * @param panelId The ID from the {@code PanelConfig}.
+     * @param viewIndex The index from the {@code ViewConfig}.
      */
-    public PanelRefreshLayout(Context context, View childView) {
+    public PanelRefreshLayout(Context context, View childView, String panelId, int viewIndex) {
         super(context);
 
         if (!(childView instanceof DatasetBacked)) {
             throw new IllegalArgumentException("View must implement DatasetBacked to be refreshed");
         }
 
+        this.panelId = panelId;
+        this.viewIndex = viewIndex;
         this.datasetBacked = (DatasetBacked) childView;
 
         setOnRefreshListener(new RefreshListener());
         addView(childView);
 
         // Must be called after the child view has been added.
         setColorScheme(R.color.swipe_refresh_orange, R.color.swipe_refresh_white,
                        R.color.swipe_refresh_orange, R.color.swipe_refresh_white);
     }
 
     @Override
     public void setDataset(Cursor cursor) {
         datasetBacked.setDataset(cursor);
+        setRefreshing(false);
     }
 
     @Override
     public void setFilterManager(FilterManager manager) {
         datasetBacked.setFilterManager(manager);
     }
 
     private class RefreshListener implements OnRefreshListener {
         @Override
         public void onRefresh() {
-            setRefreshing(false);
+            final JSONObject response = new JSONObject();
+            try {
+                response.put(JSON_KEY_PANEL_ID, panelId);
+                response.put(JSON_KEY_VIEW_INDEX, viewIndex);
+            } catch (JSONException e) {
+                Log.e(LOGTAG, "Could not create refresh message", e);
+                return;
+            }
+
+            final GeckoEvent event =
+                GeckoEvent.createBroadcastEvent("HomePanels:RefreshView", response.toString());
+            GeckoAppShell.sendEventToGecko(event);
         }
     }
 }
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -127,17 +127,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
     Services.obs.addObserver(function(s, t, d) {
         window[name].observe(s, t, d)
     }, aNotification, false);
   });
 });
 
 // Lazily-loaded JS modules that use observer notifications
 [
-  ["Home", ["HomeBanner:Get", "HomePanels:Get", "HomePanels:Authenticate",
+  ["Home", ["HomeBanner:Get", "HomePanels:Get", "HomePanels:Authenticate", "HomePanels:RefreshView",
             "HomePanels:Installed", "HomePanels:Uninstalled"], "resource://gre/modules/Home.jsm"],
 ].forEach(module => {
   let [name, notifications, resource] = module;
   XPCOMUtils.defineLazyModuleGetter(this, name, resource);
   notifications.forEach(notification => {
     Services.obs.addObserver((s,t,d) => {
       this[name].observe(s,t,d)
     }, notification, false);
--- a/mobile/android/modules/Home.jsm
+++ b/mobile/android/modules/Home.jsm
@@ -213,16 +213,35 @@ let HomePanels = (function () {
         throw "Home.panels: Invalid auth for panel.id = " + id;
       }
       if (!options.auth.authenticate || typeof options.auth.authenticate !== "function") {
         throw "Home.panels: Invalid auth authenticate function: panel.id = " + this.id;
       }
       options.auth.authenticate();
     },
 
+    "HomePanels:RefreshView": function handlePanelsRefreshView(data) {
+      data = JSON.parse(data);
+
+      let options = _registeredPanels[data.panelId]();
+      let view = options.views[data.viewIndex];
+
+      if (!view) {
+        throw "Home.panels: Invalid view for panel.id = " + data.panelId
+            + ", view.index = " + data.viewIndex;
+      }
+
+      if (!view.onrefresh || typeof view.onrefresh !== "function") {
+        throw "Home.panels: Invalid onrefresh for panel.id = " + data.panelId
+            + ", view.index = " + data.viewIndex;
+      }
+
+      view.onrefresh();
+    },
+
     "HomePanels:Installed": function handlePanelsInstalled(id) {
       let options = _registeredPanels[id]();
       if (!options.oninstall) {
         return;
       }
       if (typeof options.oninstall !== "function") {
         throw "Home.panels: Invalid oninstall function: panel.id = " + this.id;
       }