Bug 1150613 - Doorhanger should not reappear after being dismissed. r=margaret, a=Kwierso
authorChenxia Liu <liuche@mozilla.com>
Thu, 18 Jun 2015 10:53:09 -0700
changeset 280593 8c6f31ca0635206c4473a9812401dc428dc49190
parent 280592 1a81c933ca56aa063c57d1fb2d7ed498a0051753
child 280594 2137ce8f916f5ca486e5b69a4a14e8b1cceddb1d
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmargaret, Kwierso
bugs1150613
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1150613 - Doorhanger should not reappear after being dismissed. r=margaret, a=Kwierso
mobile/android/base/DoorHangerPopup.java
--- a/mobile/android/base/DoorHangerPopup.java
+++ b/mobile/android/base/DoorHangerPopup.java
@@ -2,16 +2,17 @@
  * 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 java.util.HashSet;
 
+import android.widget.PopupWindow;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.json.JSONArray;
 import org.mozilla.gecko.AppConstants.Versions;
 import org.mozilla.gecko.util.GeckoEventListener;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.widget.AnchoredPopup;
 import org.mozilla.gecko.widget.DoorHanger;
@@ -19,16 +20,17 @@ import org.mozilla.gecko.widget.DoorHang
 import android.content.Context;
 import android.util.Log;
 import android.view.View;
 import org.mozilla.gecko.widget.DoorhangerConfig;
 
 public class DoorHangerPopup extends AnchoredPopup
                              implements GeckoEventListener,
                                         Tabs.OnTabsChangedListener,
+                                        PopupWindow.OnDismissListener,
                                         DoorHanger.OnButtonClickListener {
     private static final String LOGTAG = "GeckoDoorHangerPopup";
 
     // Stores a set of all active DoorHanger notifications. A DoorHanger is
     // uniquely identified by its tabId and value.
     private final HashSet<DoorHanger> mDoorHangers;
 
     // Whether or not the doorhanger popup is disabled.
@@ -38,16 +40,18 @@ public class DoorHangerPopup extends Anc
         super(context);
 
         mDoorHangers = new HashSet<DoorHanger>();
 
         EventDispatcher.getInstance().registerGeckoThreadListener(this,
             "Doorhanger:Add",
             "Doorhanger:Remove");
         Tabs.registerOnTabsChangedListener(this);
+
+        setOnDismissListener(this);
     }
 
     void destroy() {
         EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
             "Doorhanger:Add",
             "Doorhanger:Remove");
         Tabs.unregisterOnTabsChangedListener(this);
     }
@@ -134,30 +138,23 @@ public class DoorHangerPopup extends Anc
 
     // This callback is automatically executed on the UI thread.
     @Override
     public void onTabChanged(final Tab tab, final Tabs.TabEvents msg, final Object data) {
         switch(msg) {
             case CLOSED:
                 // Remove any doorhangers for a tab when it's closed (make
                 // a temporary set to avoid a ConcurrentModificationException)
-                HashSet<DoorHanger> doorHangersToRemove = new HashSet<DoorHanger>();
-                for (DoorHanger dh : mDoorHangers) {
-                    if (dh.getTabId() == tab.getId())
-                        doorHangersToRemove.add(dh);
-                }
-                for (DoorHanger dh : doorHangersToRemove) {
-                    removeDoorHanger(dh);
-                }
+                removeTabDoorHangers(tab.getId(), true);
                 break;
 
             case LOCATION_CHANGE:
                 // Only remove doorhangers if the popup is hidden or if we're navigating to a new URL
                 if (!isShowing() || !data.equals(tab.getURL()))
-                    removeTransientDoorHangers(tab.getId());
+                    removeTabDoorHangers(tab.getId(), false);
 
                 // Update the popup if the location change was on the current tab
                 if (Tabs.getInstance().isSelectedTab(tab))
                     updatePopup();
                 break;
 
             case SELECTED:
                 // Always update the popup when a new tab is selected. This will cover cases
@@ -233,26 +230,32 @@ public class DoorHangerPopup extends Anc
      */
     void removeDoorHanger(final DoorHanger doorHanger) {
         mDoorHangers.remove(doorHanger);
         mContent.removeView(doorHanger);
     }
 
     /**
      * Removes doorhangers for a given tab.
+     * @param tabId identifier of the tab to remove doorhangers from
+     * @param forceRemove boolean for force-removing tabs. If true, all doorhangers associated
+     *                    with  the tab specified are removed; if false, only remove the doorhangers
+     *                    that are not persistent, as specified by the doorhanger options.
      *
      * This method must be called on the UI thread.
      */
-    void removeTransientDoorHangers(int tabId) {
+    void removeTabDoorHangers(int tabId, boolean forceRemove) {
         // Make a temporary set to avoid a ConcurrentModificationException
         HashSet<DoorHanger> doorHangersToRemove = new HashSet<DoorHanger>();
         for (DoorHanger dh : mDoorHangers) {
             // Only remove transient doorhangers for the given tab
-            if (dh.getTabId() == tabId && dh.shouldRemove(isShowing()))
-                doorHangersToRemove.add(dh);
+            if (dh.getTabId() == tabId
+                && (forceRemove || (!forceRemove && dh.shouldRemove(isShowing())))) {
+                    doorHangersToRemove.add(dh);
+            }
         }
 
         for (DoorHanger dh : doorHangersToRemove) {
             removeDoorHanger(dh);
         }
     }
 
     /**
@@ -323,15 +326,21 @@ public class DoorHangerPopup extends Anc
             }
         }
         if (lastVisibleDoorHanger != null) {
             lastVisibleDoorHanger.hideDivider();
         }
     }
 
     @Override
+    public void onDismiss() {
+        final int tabId = Tabs.getInstance().getSelectedTab().getId();
+        removeTabDoorHangers(tabId, true);
+    }
+
+    @Override
     public void dismiss() {
         // If the popup is focusable while it is hidden, we run into crashes
         // on pre-ICS devices when the popup gets focus before it is shown.
         setFocusable(false);
         super.dismiss();
     }
 }