Bug 1234295 - GeckoPreferences: Listen for snackbar events and display snackbars. r=mcomella
authorSebastian Kaspari <s.kaspari@gmail.com>
Fri, 08 Jan 2016 16:26:25 +0100
changeset 279762 62d40b2d384c44dd650707fcc48dbc9870dbcb1c
parent 279761 8997deb26c3426864a625b9119f4387a4020d1a2
child 279763 92e6520552764d4fdd9e0b77d28ccef7179311be
push id16997
push users.kaspari@gmail.com
push dateWed, 13 Jan 2016 14:28:26 +0000
treeherderfx-team@92e652055276 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcomella
bugs1234295
milestone46.0a1
Bug 1234295 - GeckoPreferences: Listen for snackbar events and display snackbars. r=mcomella
mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
mobile/android/base/java/org/mozilla/gecko/SnackbarHelper.java
mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -641,27 +641,17 @@ public abstract class GeckoApp
                 text += "\n\n" + url;
             }
             GeckoAppShell.openUriExternal(text, "text/plain", "", "", Intent.ACTION_SEND, title, false);
 
             // Context: Sharing via chrome list (no explicit session is active)
             Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.Method.LIST, "text");
 
         } else if ("Snackbar:Show".equals(event)) {
-            final String msg = message.getString("message");
-            final int duration = message.getInt("duration");
-
-            NativeJSObject action = message.optObject("action", null);
-
-            SnackbarHelper.showSnackbarWithAction(this,
-                    msg,
-                    duration,
-                    action != null ? action.optString("label", null) : null,
-                    new SnackbarHelper.SnackbarEventCallback(callback)
-            );
+            SnackbarHelper.showSnackbar(this, message, callback);
         } else if ("SystemUI:Visibility".equals(event)) {
             setSystemUiVisible(message.getBoolean("visible"));
 
         } else if ("ToggleChrome:Focus".equals(event)) {
             focusChrome();
 
         } else if ("ToggleChrome:Hide".equals(event)) {
             toggleChrome(false);
--- a/mobile/android/base/java/org/mozilla/gecko/SnackbarHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/SnackbarHelper.java
@@ -1,16 +1,17 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * 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;
 
 import org.mozilla.gecko.util.EventCallback;
+import org.mozilla.gecko.util.NativeJSObject;
 
 import android.app.Activity;
 import android.support.design.widget.Snackbar;
 import android.support.v4.content.ContextCompat;
 import android.text.TextUtils;
 import android.view.View;
 
 import java.lang.ref.WeakReference;
@@ -24,17 +25,17 @@ public class SnackbarHelper {
      * Combined interface for handling all callbacks from a snackbar because anonymous classes can only extend one
      * interface or class.
      */
     public static abstract class SnackbarCallback extends Snackbar.Callback implements View.OnClickListener {}
 
     /**
      * SnackbarCallback implementation for delegating snackbar events to an EventCallback.
      */
-    public static class SnackbarEventCallback extends SnackbarCallback {
+    private static class SnackbarEventCallback extends SnackbarCallback {
         private EventCallback callback;
 
         public SnackbarEventCallback(EventCallback callback) {
             this.callback = callback;
         }
 
         @Override
         public synchronized void onClick(View view) {
@@ -67,16 +68,32 @@ public class SnackbarHelper {
      * @param message The text to show. Can be formatted text.
      * @param duration How long to display the message.
      */
     public static void showSnackbar(Activity activity, String message, int duration) {
         showSnackbarWithAction(activity, message, duration, null, null);
     }
 
     /**
+     * Build and show a snackbar from a Gecko Snackbar:Show event.
+     */
+    public static void showSnackbar(Activity activity, final NativeJSObject object, final EventCallback callback) {
+        final String message = object.getString("message");
+        final int duration = object.getInt("duration");
+
+        NativeJSObject action = object.optObject("action", null);
+
+        showSnackbarWithAction(activity,
+                message,
+                duration,
+                action != null ? action.optString("label", null) : null,
+                new SnackbarHelper.SnackbarEventCallback(callback));
+    }
+
+    /**
      * Show a snackbar to display a message and an action.
      *
      * @param activity Activity to show the snackbar in.
      * @param message The text to show. Can be formatted text.
      * @param duration How long to display the message.
      * @param action Action text to display.
      * @param callback Callback to be invoked when the action is clicked or the snackbar is dismissed.
      */
--- a/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
+++ b/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
@@ -30,20 +30,22 @@ import org.mozilla.gecko.Telemetry;
 import org.mozilla.gecko.TelemetryContract;
 import org.mozilla.gecko.TelemetryContract.Method;
 import org.mozilla.gecko.background.common.GlobalConstants;
 import org.mozilla.gecko.db.BrowserContract.SuggestedSites;
 import org.mozilla.gecko.restrictions.Restrictable;
 import org.mozilla.gecko.tabqueue.TabQueueHelper;
 import org.mozilla.gecko.updater.UpdateService;
 import org.mozilla.gecko.updater.UpdateServiceHelper;
+import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.GeckoEventListener;
 import org.mozilla.gecko.util.HardwareUtils;
 import org.mozilla.gecko.util.InputOptionsUtils;
 import org.mozilla.gecko.util.NativeEventListener;
+import org.mozilla.gecko.util.NativeJSObject;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.widget.FloatingHintEditText;
 
 import android.app.ActionBar;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.Fragment;
 import android.app.FragmentManager;
@@ -89,16 +91,17 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
 public class GeckoPreferences
 extends PreferenceActivity
 implements
 GeckoActivityStatus,
 GeckoEventListener,
+NativeEventListener,
 OnPreferenceChangeListener,
 OnSharedPreferenceChangeListener
 {
     private static final String LOGTAG = "GeckoPreferences";
 
     // We have a white background, which makes transitions on
     // some devices look bad. Don't use transitions on those
     // devices.
@@ -358,19 +361,22 @@ OnSharedPreferenceChangeListener
                 Telemetry.startUISession(TelemetryContract.Session.SETTINGS);
             }
 
             // We don't include a title in the XML, so set it here, in a locale-aware fashion.
             updateTitleForPrefsResource(res);
             addPreferencesFromResource(res);
         }
 
-        EventDispatcher.getInstance().registerGeckoThreadListener(this,
+        EventDispatcher.getInstance().registerGeckoThreadListener((GeckoEventListener) this,
             "Sanitize:Finished");
 
+        EventDispatcher.getInstance().registerGeckoThreadListener((NativeEventListener) this,
+            "Snackbar:Show");
+
         // Add handling for long-press click.
         // This is only for Android 3.0 and below (which use the long-press-context-menu paradigm).
         final ListView mListView = getListView();
         mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
             @Override
             public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                 // Call long-click handler if it the item implements it.
                 final ListAdapter listAdapter = ((ListView) parent).getAdapter();
@@ -509,18 +515,22 @@ OnSharedPreferenceChangeListener
         }
 
         Telemetry.sendUIEvent(TelemetryContract.Event.CANCEL, Method.BACK, "settings");
     }
 
     @Override
     protected void onDestroy() {
         super.onDestroy();
-        EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
+        EventDispatcher.getInstance().unregisterGeckoThreadListener((GeckoEventListener) this,
             "Sanitize:Finished");
+
+        EventDispatcher.getInstance().unregisterGeckoThreadListener((NativeEventListener) this,
+            "Snackbar:Show");
+
         if (mPrefsRequestId > 0) {
             PrefsHelper.removeObserver(mPrefsRequestId);
         }
 
         // The intent extras will be null if this is the top-level settings
         // activity. In that case, we want to end the SETTINGS telmetry session.
         // For HC+ versions of Android this is handled in GeckoPreferenceFragment.
         if (Versions.preHC && getIntent().getExtras() == null) {
@@ -624,16 +634,23 @@ OnSharedPreferenceChangeListener
                         getString(stringRes),
                         Snackbar.LENGTH_SHORT);
             }
         } catch (Exception e) {
             Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
         }
     }
 
+    @Override
+    public void handleMessage(final String event, final NativeJSObject message, final EventCallback callback) {
+        if ("Snackbar:Show".equals(event)) {
+            SnackbarHelper.showSnackbar(this, message, callback);
+        }
+    }
+
     /**
       * Initialize all of the preferences (native of Gecko ones) for this screen.
       *
       * @param prefs The android.preference.PreferenceGroup to initialize
       * @return The integer id for the PrefsHelper.PrefHandlerBase listener added
       *         to monitor changes to Gecko prefs.
       */
     public int setupPreferences(PreferenceGroup prefs) {