Bug 1320603 - Revert to global EventDispatcher for certain events; r=sebastian
authorJim Chen <nchen@mozilla.com>
Wed, 30 Nov 2016 14:01:20 -0500
changeset 324833 e7ae0014cb1e50baaead4a0dee1dc2d014390724
parent 324832 c1e18cb7926e0acc31c3954d1160a786f03b1f1a
child 324834 1309c56ba4cddb537cd990409e05f353926b1a1f
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewerssebastian
bugs1320603
milestone53.0a1
Bug 1320603 - Revert to global EventDispatcher for certain events; r=sebastian These events are not accessed through GeckoApp, and should therefore use the global EventDispatcher rather than the per-GeckoApp/GeckoView EventDispatcher. Otherwise, we could run into situations where we end up registering / unregistering the same event using different EventDispatcher instances, causing exceptions like this one.
mobile/android/base/java/org/mozilla/gecko/AccountsHelper.java
mobile/android/base/java/org/mozilla/gecko/FindInPageBar.java
mobile/android/base/java/org/mozilla/gecko/MediaCastingBar.java
mobile/android/base/java/org/mozilla/gecko/MediaPlayerManager.java
mobile/android/base/java/org/mozilla/gecko/SharedPreferencesHelper.java
mobile/android/base/java/org/mozilla/gecko/ZoomedView.java
mobile/android/base/java/org/mozilla/gecko/home/BrowserSearch.java
mobile/android/base/java/org/mozilla/gecko/home/HomeBanner.java
mobile/android/base/java/org/mozilla/gecko/home/PanelInfoManager.java
mobile/android/base/java/org/mozilla/gecko/preferences/SearchPreferenceCategory.java
mobile/android/base/java/org/mozilla/gecko/reader/ReadingListHelper.java
mobile/android/base/java/org/mozilla/gecko/toolbar/PageActionLayout.java
mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java
--- a/mobile/android/base/java/org/mozilla/gecko/AccountsHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/AccountsHelper.java
@@ -47,38 +47,28 @@ public class AccountsHelper implements N
 
     protected final Context mContext;
     protected final GeckoProfile mProfile;
 
     public AccountsHelper(Context context, GeckoProfile profile) {
         mContext = context;
         mProfile = profile;
 
-        EventDispatcher dispatcher = GeckoApp.getEventDispatcher();
-        if (dispatcher == null) {
-            Log.e(LOGTAG, "Gecko event dispatcher must not be null", new RuntimeException());
-            return;
-        }
-        dispatcher.registerGeckoThreadListener(this,
+        EventDispatcher.getInstance().registerGeckoThreadListener(this,
                 "Accounts:CreateFirefoxAccountFromJSON",
                 "Accounts:UpdateFirefoxAccountFromJSON",
                 "Accounts:Create",
                 "Accounts:DeleteFirefoxAccount",
                 "Accounts:Exist",
                 "Accounts:ProfileUpdated",
                 "Accounts:ShowSyncPreferences");
     }
 
     public synchronized void uninit() {
-        EventDispatcher dispatcher = GeckoApp.getEventDispatcher();
-        if (dispatcher == null) {
-            Log.e(LOGTAG, "Gecko event dispatcher must not be null", new RuntimeException());
-            return;
-        }
-        dispatcher.unregisterGeckoThreadListener(this,
+        EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
                 "Accounts:CreateFirefoxAccountFromJSON",
                 "Accounts:UpdateFirefoxAccountFromJSON",
                 "Accounts:Create",
                 "Accounts:DeleteFirefoxAccount",
                 "Accounts:Exist",
                 "Accounts:ProfileUpdated",
                 "Accounts:ShowSyncPreferences");
     }
--- a/mobile/android/base/java/org/mozilla/gecko/FindInPageBar.java
+++ b/mobile/android/base/java/org/mozilla/gecko/FindInPageBar.java
@@ -62,17 +62,17 @@ public class FindInPageBar extends Linea
                 }
                 return false;
             }
         });
 
         mStatusText = (TextView) content.findViewById(R.id.find_status);
 
         mInflated = true;
-        GeckoApp.getEventDispatcher().registerGeckoThreadListener(this,
+        EventDispatcher.getInstance().registerGeckoThreadListener(this,
             "FindInPage:MatchesCountResult",
             "TextSelection:Data");
     }
 
     public void show() {
         if (!mInflated)
             inflateContent();
 
@@ -107,17 +107,17 @@ public class FindInPageBar extends Linea
         Context context = view.getContext();
         return (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
      }
 
     public void onDestroy() {
         if (!mInflated) {
             return;
         }
-        GeckoApp.getEventDispatcher().unregisterGeckoThreadListener(this,
+        EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
             "FindInPage:MatchesCountResult",
             "TextSelection:Data");
     }
 
     private void onMatchesCountResult(final int total, final int current, final int limit, final String searchString) {
         if (total == -1) {
             updateResult(Integer.toString(limit) + "+");
         } else if (total > 0) {
--- a/mobile/android/base/java/org/mozilla/gecko/MediaCastingBar.java
+++ b/mobile/android/base/java/org/mozilla/gecko/MediaCastingBar.java
@@ -27,23 +27,18 @@ public class MediaCastingBar extends Rel
     private ImageButton mMediaPlay;
     private ImageButton mMediaPause;
     private ImageButton mMediaStop;
 
     private boolean mInflated;
 
     public MediaCastingBar(Context context, AttributeSet attrs) {
         super(context, attrs);
-    }
 
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        GeckoApp.getEventDispatcher().registerGeckoThreadListener(this,
+        EventDispatcher.getInstance().registerGeckoThreadListener(this,
             "Casting:Started",
             "Casting:Paused",
             "Casting:Playing",
             "Casting:Stopped");
     }
 
     public void inflateContent() {
         LayoutInflater inflater = LayoutInflater.from(getContext());
@@ -72,27 +67,21 @@ public class MediaCastingBar extends Rel
         setVisibility(VISIBLE);
     }
 
     public void hide() {
         setVisibility(GONE);
     }
 
     public void onDestroy() {
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        GeckoApp.getEventDispatcher().unregisterGeckoThreadListener(this,
+        EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
             "Casting:Started",
             "Casting:Paused",
             "Casting:Playing",
             "Casting:Stopped");
-
-        super.onDetachedFromWindow();
     }
 
     // View.OnClickListener implementation
     @Override
     public void onClick(View v) {
         final int viewId = v.getId();
 
         if (viewId == R.id.media_play) {
--- a/mobile/android/base/java/org/mozilla/gecko/MediaPlayerManager.java
+++ b/mobile/android/base/java/org/mozilla/gecko/MediaPlayerManager.java
@@ -71,47 +71,49 @@ public class MediaPlayerManager extends 
         }
     }
 
     protected MediaRouter mediaRouter = null;
     protected final Map<String, GeckoMediaPlayer> players = new HashMap<String, GeckoMediaPlayer>();
     protected final Map<String, GeckoPresentationDisplay> displays = new HashMap<String, GeckoPresentationDisplay>(); // used for Presentation API
 
     @Override
-    public void onStart() {
-        super.onStart();
-        GeckoApp.getEventDispatcher().registerGeckoThreadListener(this,
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        EventDispatcher.getInstance().registerGeckoThreadListener(this,
                                                                   "MediaPlayer:Load",
                                                                   "MediaPlayer:Start",
                                                                   "MediaPlayer:Stop",
                                                                   "MediaPlayer:Play",
                                                                   "MediaPlayer:Pause",
                                                                   "MediaPlayer:End",
                                                                   "MediaPlayer:Mirror",
                                                                   "MediaPlayer:Message",
                                                                   "AndroidCastDevice:Start",
                                                                   "AndroidCastDevice:Stop",
                                                                   "AndroidCastDevice:SyncDevice");
     }
 
     @Override
-    public void onStop() {
-        GeckoApp.getEventDispatcher().unregisterGeckoThreadListener(this,
+    public void onDestroy() {
+        EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
                                                                     "MediaPlayer:Load",
                                                                     "MediaPlayer:Start",
                                                                     "MediaPlayer:Stop",
                                                                     "MediaPlayer:Play",
                                                                     "MediaPlayer:Pause",
                                                                     "MediaPlayer:End",
                                                                     "MediaPlayer:Mirror",
                                                                     "MediaPlayer:Message",
                                                                     "AndroidCastDevice:Start",
                                                                     "AndroidCastDevice:Stop",
                                                                     "AndroidCastDevice:SyncDevice");
-        super.onStop();
+
+        super.onDestroy();
     }
 
     // GeckoEventListener implementation
     @Override
     public void handleMessage(String event, final NativeJSObject message, final EventCallback callback) {
         debug(event);
         if (event.startsWith("MediaPlayer:")) {
             final GeckoMediaPlayer player = players.get(message.getString("id"));
--- a/mobile/android/base/java/org/mozilla/gecko/SharedPreferencesHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/SharedPreferencesHelper.java
@@ -59,34 +59,24 @@ public final class SharedPreferencesHelp
     // handleObserve, which is called from Gecko serially.
     protected final Map<String, SharedPreferences.OnSharedPreferenceChangeListener> mListeners;
 
     public SharedPreferencesHelper(Context context) {
         mContext = context;
 
         mListeners = new HashMap<String, SharedPreferences.OnSharedPreferenceChangeListener>();
 
-        EventDispatcher dispatcher = GeckoApp.getEventDispatcher();
-        if (dispatcher == null) {
-            Log.e(LOGTAG, "Gecko event dispatcher must not be null", new RuntimeException());
-            return;
-        }
-        dispatcher.registerGeckoThreadListener(this,
+        EventDispatcher.getInstance().registerGeckoThreadListener(this,
             "SharedPreferences:Set",
             "SharedPreferences:Get",
             "SharedPreferences:Observe");
     }
 
     public synchronized void uninit() {
-        EventDispatcher dispatcher = GeckoApp.getEventDispatcher();
-        if (dispatcher == null) {
-            Log.e(LOGTAG, "Gecko event dispatcher must not be null", new RuntimeException());
-            return;
-        }
-        dispatcher.unregisterGeckoThreadListener(this,
+        EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
             "SharedPreferences:Set",
             "SharedPreferences:Get",
             "SharedPreferences:Observe");
     }
 
     private SharedPreferences getSharedPreferences(JSONObject message) throws JSONException {
         final Scope scope = Scope.forKey(message.getString("scope"));
         switch (scope) {
--- a/mobile/android/base/java/org/mozilla/gecko/ZoomedView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/ZoomedView.java
@@ -235,32 +235,42 @@ public class ZoomedView extends FrameLay
         animationStart = new PointF();
         requestRenderRunnable = new Runnable() {
             @Override
             public void run() {
                 requestZoomedViewRender();
             }
         };
         touchListener = new ZoomedViewTouchListener();
-        GeckoApp.getEventDispatcher().registerGeckoThreadListener(this,
-                "Gesture:clusteredLinksClicked", "Window:Resize", "Content:LocationChange",
-                "Gesture:CloseZoomedView", "Browser:ZoomToPageWidth", "Browser:ZoomToRect",
-                "FormAssist:AutoComplete", "FormAssist:Hide");
+        EventDispatcher.getInstance().registerGeckoThreadListener(this,
+                "Gesture:clusteredLinksClicked",
+                "Window:Resize",
+                "Content:LocationChange",
+                "Gesture:CloseZoomedView",
+                "Browser:ZoomToPageWidth",
+                "Browser:ZoomToRect",
+                "FormAssist:AutoComplete",
+                "FormAssist:Hide");
     }
 
     void destroy() {
         if (prefObserver != null) {
             PrefsHelper.removeObserver(prefObserver);
             prefObserver = null;
         }
         ThreadUtils.removeCallbacksFromUiThread(requestRenderRunnable);
-        GeckoApp.getEventDispatcher().unregisterGeckoThreadListener(this,
-                "Gesture:clusteredLinksClicked", "Window:Resize", "Content:LocationChange",
-                "Gesture:CloseZoomedView", "Browser:ZoomToPageWidth", "Browser:ZoomToRect",
-                "FormAssist:AutoComplete", "FormAssist:Hide");
+        EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
+                "Gesture:clusteredLinksClicked",
+                "Window:Resize",
+                "Content:LocationChange",
+                "Gesture:CloseZoomedView",
+                "Browser:ZoomToPageWidth",
+                "Browser:ZoomToRect",
+                "FormAssist:AutoComplete",
+                "FormAssist:Hide");
     }
 
     // This method (onFinishInflate) is called only when the zoomed view class is used inside
     // an xml structure <org.mozilla.gecko.ZoomedView ...
     // It won't be called if the class is used from java code like "new  ZoomedView(context);"
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
--- a/mobile/android/base/java/org/mozilla/gecko/home/BrowserSearch.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/BrowserSearch.java
@@ -16,17 +16,16 @@ import java.util.List;
 import java.util.Locale;
 
 import android.content.SharedPreferences;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import org.mozilla.gecko.EventDispatcher;
-import org.mozilla.gecko.GeckoApp;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoSharedPrefs;
 import org.mozilla.gecko.PrefsHelper;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.SuggestClient;
 import org.mozilla.gecko.Tab;
 import org.mozilla.gecko.Tabs;
 import org.mozilla.gecko.Telemetry;
@@ -304,17 +303,17 @@ public class BrowserSearch extends HomeF
 
         return mView;
     }
 
     @Override
     public void onDestroyView() {
         super.onDestroyView();
 
-        GeckoApp.getEventDispatcher().unregisterGeckoThreadListener(this,
+        EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
             "SearchEngines:Data");
 
         mSearchEngineBar.setAdapter(null);
         mSearchEngineBar = null;
 
         mList.setAdapter(null);
         mList = null;
 
@@ -404,17 +403,17 @@ public class BrowserSearch extends HomeF
                 if (selected instanceof SearchEngineRow) {
                     return selected.onKeyDown(keyCode, event);
                 }
                 return false;
             }
         });
 
         registerForContextMenu(mList);
-        GeckoApp.getEventDispatcher().registerGeckoThreadListener(this,
+        EventDispatcher.getInstance().registerGeckoThreadListener(this,
             "SearchEngines:Data");
 
         mSearchEngineBar.setOnSearchBarClickListener(this);
     }
 
     @Override
     public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
         if (!(menuInfo instanceof HomeContextMenuInfo)) {
--- a/mobile/android/base/java/org/mozilla/gecko/home/HomeBanner.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/HomeBanner.java
@@ -1,17 +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.home;
 
 import org.json.JSONObject;
-import org.mozilla.gecko.GeckoApp;
+import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.animation.PropertyAnimator;
 import org.mozilla.gecko.animation.PropertyAnimator.Property;
 import org.mozilla.gecko.animation.ViewHelper;
 import org.mozilla.gecko.util.FloatUtils;
 import org.mozilla.gecko.util.ResourceDrawableUtils;
 import org.mozilla.gecko.util.GeckoEventListener;
@@ -109,24 +109,24 @@ public class HomeBanner extends LinearLa
             public void onClick(View v) {
                 HomeBanner.this.dismiss();
 
                 // Send the current message id back to JS.
                 GeckoAppShell.notifyObservers("HomeBanner:Click", (String) getTag());
             }
         });
 
-        GeckoApp.getEventDispatcher().registerGeckoThreadListener(this, "HomeBanner:Data");
+        EventDispatcher.getInstance().registerGeckoThreadListener(this, "HomeBanner:Data");
     }
 
     @Override
     public void onDetachedFromWindow() {
         super.onDetachedFromWindow();
 
-        GeckoApp.getEventDispatcher().unregisterGeckoThreadListener(this, "HomeBanner:Data");
+        EventDispatcher.getInstance().unregisterGeckoThreadListener(this, "HomeBanner:Data");
     }
 
     public void setScrollingPages(boolean scrollingPages) {
         mScrollingPages = scrollingPages;
     }
 
     public void setOnDismissListener(OnDismissListener listener) {
         mOnDismissListener = listener;
--- a/mobile/android/base/java/org/mozilla/gecko/home/PanelInfoManager.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/PanelInfoManager.java
@@ -9,17 +9,16 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.mozilla.gecko.EventDispatcher;
-import org.mozilla.gecko.GeckoApp;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.home.HomeConfig.PanelConfig;
 import org.mozilla.gecko.util.GeckoEventListener;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -73,17 +72,17 @@ public class PanelInfoManager implements
      * @param callback onComplete will be called on the UI thread.
      */
     public void requestPanelsById(Set<String> ids, RequestCallback callback) {
         final int requestId = sRequestId.getAndIncrement();
 
         synchronized (sCallbacks) {
             // If there are no pending callbacks, register the event listener.
             if (sCallbacks.size() == 0) {
-                GeckoApp.getEventDispatcher().registerGeckoThreadListener(this,
+                EventDispatcher.getInstance().registerGeckoThreadListener(this,
                     "HomePanels:Data");
             }
             sCallbacks.put(requestId, callback);
         }
 
         final JSONObject message = new JSONObject();
         try {
             message.put("requestId", requestId);
@@ -132,17 +131,17 @@ public class PanelInfoManager implements
             final int requestId = message.getInt("requestId");
 
             synchronized (sCallbacks) {
                 callback = sCallbacks.get(requestId);
                 sCallbacks.delete(requestId);
 
                 // Unregister the event listener if there are no more pending callbacks.
                 if (sCallbacks.size() == 0) {
-                    GeckoApp.getEventDispatcher().unregisterGeckoThreadListener(this,
+                    EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
                         "HomePanels:Data");
                 }
             }
 
             ThreadUtils.postToUiThread(new Runnable() {
                 @Override
                 public void run() {
                     callback.onComplete(panelInfos);
--- a/mobile/android/base/java/org/mozilla/gecko/preferences/SearchPreferenceCategory.java
+++ b/mobile/android/base/java/org/mozilla/gecko/preferences/SearchPreferenceCategory.java
@@ -9,17 +9,16 @@ import android.preference.Preference;
 import android.util.AttributeSet;
 import android.util.Log;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import org.mozilla.gecko.EventDispatcher;
-import org.mozilla.gecko.GeckoApp;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.Telemetry;
 import org.mozilla.gecko.TelemetryContract;
 import org.mozilla.gecko.TelemetryContract.Method;
 import org.mozilla.gecko.util.GeckoEventListener;
 import org.mozilla.gecko.util.ThreadUtils;
 
 public class SearchPreferenceCategory extends CustomListCategory implements GeckoEventListener {
@@ -37,25 +36,25 @@ public class SearchPreferenceCategory ex
         super(context, attrs, defStyle);
     }
 
     @Override
     protected void onAttachedToActivity() {
         super.onAttachedToActivity();
 
         // Register for SearchEngines messages and request list of search engines from Gecko.
-        GeckoApp.getEventDispatcher().registerGeckoThreadListener(this, "SearchEngines:Data");
+        EventDispatcher.getInstance().registerGeckoThreadListener(this, "SearchEngines:Data");
         GeckoAppShell.notifyObservers("SearchEngines:GetVisible", null);
     }
 
     @Override
     protected void onPrepareForRemoval() {
         super.onPrepareForRemoval();
 
-        GeckoApp.getEventDispatcher().unregisterGeckoThreadListener(this, "SearchEngines:Data");
+        EventDispatcher.getInstance().unregisterGeckoThreadListener(this, "SearchEngines:Data");
     }
 
     @Override
     public void setDefault(CustomListPreference item) {
         super.setDefault(item);
 
         sendGeckoEngineEvent("SearchEngines:SetDefault", item.getTitle().toString());
 
--- a/mobile/android/base/java/org/mozilla/gecko/reader/ReadingListHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/reader/ReadingListHelper.java
@@ -4,17 +4,16 @@
 
 package org.mozilla.gecko.reader;
 
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import org.mozilla.gecko.AboutPages;
 import org.mozilla.gecko.EventDispatcher;
-import org.mozilla.gecko.GeckoApp;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoProfile;
 import org.mozilla.gecko.db.BrowserDB;
 import org.mozilla.gecko.icons.IconRequest;
 import org.mozilla.gecko.icons.Icons;
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.NativeEventListener;
 import org.mozilla.gecko.util.NativeJSObject;
@@ -31,22 +30,22 @@ public final class ReadingListHelper imp
 
     protected final Context context;
     private final BrowserDB db;
 
     public ReadingListHelper(Context context, GeckoProfile profile) {
         this.context = context;
         this.db = BrowserDB.from(profile);
 
-        GeckoApp.getEventDispatcher().registerGeckoThreadListener((NativeEventListener) this,
+        EventDispatcher.getInstance().registerGeckoThreadListener((NativeEventListener) this,
             "Reader:FaviconRequest", "Reader:AddedToCache");
     }
 
     public void uninit() {
-        GeckoApp.getEventDispatcher().unregisterGeckoThreadListener((NativeEventListener) this,
+        EventDispatcher.getInstance().unregisterGeckoThreadListener((NativeEventListener) this,
             "Reader:FaviconRequest", "Reader:AddedToCache");
     }
 
     @Override
     public void handleMessage(final String event, final NativeJSObject message,
                               final EventCallback callback) {
         switch (event) {
             case "Reader:FaviconRequest": {
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/PageActionLayout.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/PageActionLayout.java
@@ -1,16 +1,16 @@
 /* -*- 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.toolbar;
 
-import org.mozilla.gecko.GeckoApp;
+import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.util.ResourceDrawableUtils;
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.NativeEventListener;
 import org.mozilla.gecko.util.NativeJSObject;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.widget.GeckoPopupMenu;
@@ -56,24 +56,24 @@ public class PageActionLayout extends Li
         setNumberShown(DEFAULT_PAGE_ACTIONS_SHOWN);
         refreshPageActionIcons();
     }
 
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
 
-        GeckoApp.getEventDispatcher().registerGeckoThreadListener(this,
+        EventDispatcher.getInstance().registerGeckoThreadListener(this,
             "PageActions:Add",
             "PageActions:Remove");
     }
 
     @Override
     protected void onDetachedFromWindow() {
-        GeckoApp.getEventDispatcher().unregisterGeckoThreadListener(this,
+        EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
             "PageActions:Add",
             "PageActions:Remove");
 
         super.onDetachedFromWindow();
     }
 
     private void setNumberShown(int count) {
         ThreadUtils.assertOnUiThread();
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java
@@ -16,17 +16,16 @@ import android.support.v4.widget.TextVie
 import android.widget.ImageView;
 import android.widget.Toast;
 import org.json.JSONException;
 import org.json.JSONArray;
 import org.mozilla.gecko.AboutPages;
 import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.R;
-import org.mozilla.gecko.GeckoApp;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.SiteIdentity;
 import org.mozilla.gecko.SiteIdentity.SecurityMode;
 import org.mozilla.gecko.SiteIdentity.MixedMode;
 import org.mozilla.gecko.SiteIdentity.TrackingMode;
 import org.mozilla.gecko.SnackbarBuilder;
 import org.mozilla.gecko.Tab;
 import org.mozilla.gecko.Tabs;
@@ -96,17 +95,17 @@ public class SiteIdentityPopup extends A
         super(context);
 
         mResources = mContext.getResources();
 
         mContentButtonClickListener = new ContentNotificationButtonListener();
     }
 
     void registerListeners() {
-        GeckoApp.getEventDispatcher().registerGeckoThreadListener(this,
+        EventDispatcher.getInstance().registerGeckoThreadListener(this,
                                                                   "Doorhanger:Logins",
                                                                   "Permissions:CheckResult");
     }
 
     @Override
     protected void init() {
         super.init();
 
@@ -556,17 +555,17 @@ public class SiteIdentityPopup extends A
             lastVisibleDoorHanger.hideDivider();
         }
     }
 
     void destroy() {
     }
 
     void unregisterListeners() {
-        GeckoApp.getEventDispatcher().unregisterGeckoThreadListener(this,
+        EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
                                                                     "Doorhanger:Logins",
                                                                     "Permissions:CheckResult");
     }
 
     @Override
     public void dismiss() {
         super.dismiss();
         removeTrackingContentNotification();