Bug 1257319 - Convert broadcast event usage in HomeConfig.java; r=margaret
☠☠ backed out by f7d63892ad2c ☠ ☠
authorJim Chen <nchen@mozilla.com>
Tue, 22 Mar 2016 22:24:31 -0400
changeset 289970 ba16cc23d7c44fb323bab01225019740f33c046d
parent 289969 3e80b5052d0b33bdbdeb7b670d38bfeea03ac7ae
child 289971 9d6577fd74f3cd1fb026623a53d18dccd4588e53
push id18337
push usercbook@mozilla.com
push dateWed, 23 Mar 2016 15:30:25 +0000
treeherderfx-team@67ac681f7e53 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmargaret
bugs1257319
milestone48.0a1
Bug 1257319 - Convert broadcast event usage in HomeConfig.java; r=margaret HomeConfig.java saved a list of events to be sent later in a batch. This patch makes it save a pair of strings instead, and the strings are later used to make calls to GeckoAppShell. The patch also makes two small optimizations. It makes the queue an ArrayList instead of a LinkedList to save memory. It also makes copying the queue a swap instead of a true copy.
mobile/android/base/java/org/mozilla/gecko/home/HomeConfig.java
--- a/mobile/android/base/java/org/mozilla/gecko/home/HomeConfig.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/HomeConfig.java
@@ -23,16 +23,17 @@ import org.mozilla.gecko.GeckoEvent;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import android.content.Context;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.Pair;
 
 public final class HomeConfig {
     /**
      * Used to determine what type of HomeFragment subclass to use when creating
      * a given panel. With the exception of DYNAMIC, all of these types correspond
      * to a default set of built-in panels. The DYNAMIC panel type is used by
      * third-party services to create panels with varying types of content.
      */
@@ -1135,31 +1136,33 @@ public final class HomeConfig {
      * {@code Editor} is *not* thread-safe. You can only make calls on it
      * from the thread where it was originally created. It will throw an
      * exception if you don't follow this invariant.
      */
     public static class Editor implements Iterable<PanelConfig> {
         private final HomeConfig mHomeConfig;
         private final Map<String, PanelConfig> mConfigMap;
         private final List<String> mConfigOrder;
-        private final List<GeckoEvent> mEventQueue;
         private final Thread mOriginalThread;
 
+        // Each Pair represents parameters to a GeckoAppShell.notifyObservers call;
+        // the first String is the observer topic and the second string is the notification data.
+        private List<Pair<String, String>> mNotificationQueue;
         private PanelConfig mDefaultPanel;
         private int mEnabledCount;
 
         private boolean mHasChanged;
         private final boolean mIsFromDefault;
 
         private Editor(HomeConfig homeConfig, State configState) {
             mHomeConfig = homeConfig;
             mOriginalThread = Thread.currentThread();
             mConfigMap = new HashMap<String, PanelConfig>();
             mConfigOrder = new LinkedList<String>();
-            mEventQueue = new LinkedList<GeckoEvent>();
+            mNotificationQueue = new ArrayList<>();
 
             mIsFromDefault = configState.isDefault();
 
             initFromState(configState);
         }
 
         /**
          * Initialize the initial state of the editor from the given
@@ -1361,17 +1364,18 @@ public final class HomeConfig {
                 mEnabledCount++;
                 if (mEnabledCount == 1 || panelConfig.isDefault()) {
                     setDefault(panelConfig.getId());
                 }
 
                 installed = true;
 
                 // Add an event to the queue if a new panel is successfully installed.
-                mEventQueue.add(GeckoEvent.createBroadcastEvent("HomePanels:Installed", panelConfig.getId()));
+                mNotificationQueue.add(new Pair<String, String>(
+                        "HomePanels:Installed", panelConfig.getId()));
             }
 
             mHasChanged = true;
             return installed;
         }
 
         /**
          * Removes an existing panel.
@@ -1397,17 +1401,17 @@ public final class HomeConfig {
                 mEnabledCount--;
             }
 
             if (isCurrentDefaultPanel(panelConfig)) {
                 findNewDefault();
             }
 
             // Add an event to the queue if a panel is successfully uninstalled.
-            mEventQueue.add(GeckoEvent.createBroadcastEvent("HomePanels:Uninstalled", panelId));
+            mNotificationQueue.add(new Pair<String, String>("HomePanels:Uninstalled", panelId));
 
             mHasChanged = true;
             return true;
         }
 
         /**
          * Moves panel associated with panelId to the specified position.
          *
@@ -1469,28 +1473,28 @@ public final class HomeConfig {
             ThreadUtils.assertOnThread(mOriginalThread);
 
             // We're about to save the current state in the background thread
             // so we should use a deep copy of the PanelConfig instances to
             // avoid saving corrupted state.
             final State newConfigState =
                     new State(mHomeConfig, makeOrderedCopy(true), isDefault());
 
-            // Copy the event queue to a new list, so that we only modify mEventQueue on
+            // Copy the event queue to a new list, so that we only modify mNotificationQueue on
             // the original thread where it was created.
-            final LinkedList<GeckoEvent> eventQueueCopy = new LinkedList<GeckoEvent>(mEventQueue);
-            mEventQueue.clear();
+            final List<Pair<String, String>> copiedQueue = mNotificationQueue;
+            mNotificationQueue = new ArrayList<>();
 
             ThreadUtils.getBackgroundHandler().post(new Runnable() {
                 @Override
                 public void run() {
                     mHomeConfig.save(newConfigState);
 
                     // Send pending events after the new config is saved.
-                    sendEventsToGecko(eventQueueCopy);
+                    sendNotificationsToGecko(copiedQueue);
                 }
             });
 
             return newConfigState;
         }
 
         /**
          * Saves the current {@code Editor} state synchronously in the
@@ -1504,18 +1508,18 @@ public final class HomeConfig {
             final State newConfigState =
                     new State(mHomeConfig, makeOrderedCopy(false), isDefault());
 
             // This is a synchronous blocking operation, hence no
             // need to deep copy the current PanelConfig instances.
             mHomeConfig.save(newConfigState);
 
             // Send pending events after the new config is saved.
-            sendEventsToGecko(mEventQueue);
-            mEventQueue.clear();
+            sendNotificationsToGecko(mNotificationQueue);
+            mNotificationQueue.clear();
 
             return newConfigState;
         }
 
         /**
          * Returns whether the {@code Editor} represents the default
          * {@code HomeConfig} configuration without any unsaved changes.
          */
@@ -1524,19 +1528,19 @@ public final class HomeConfig {
 
             return (!mHasChanged && mIsFromDefault);
         }
 
         public boolean isEmpty() {
             return mConfigMap.isEmpty();
         }
 
-        private void sendEventsToGecko(List<GeckoEvent> events) {
-            for (GeckoEvent e : events) {
-                GeckoAppShell.sendEventToGecko(e);
+        private void sendNotificationsToGecko(List<Pair<String, String>> notifications) {
+            for (Pair<String, String> p : notifications) {
+                GeckoAppShell.notifyObservers(p.first, p.second);
             }
         }
 
         private class EditorIterator implements Iterator<PanelConfig> {
             private final Iterator<String> mOrderIterator;
 
             public EditorIterator() {
                 mOrderIterator = mConfigOrder.iterator();