Bug 1330836 - Only send 'network config/status changed' events to Gecko if something actually changed r=jchen draft
authorGrigory Kruglov <gkruglov@mozilla.com>
Mon, 06 Feb 2017 12:17:57 -0800
changeset 479508 4a4503fed3747eea5432d295b8f4410f64d11faf
parent 469123 f3d187bd0733b1182dffc97b5dfe623e18f92a44
child 544701 05329830212090e2e875f0454b7ff10f96522175
push id44272
push usergkruglov@mozilla.com
push dateMon, 06 Feb 2017 20:16:50 +0000
reviewersjchen
bugs1330836
milestone54.0a1
Bug 1330836 - Only send 'network config/status changed' events to Gecko if something actually changed r=jchen MozReview-Commit-ID: CrlRDu8MbhY
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoNetworkManager.java
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoNetworkManager.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoNetworkManager.java
@@ -40,16 +40,20 @@ import android.util.Log;
  * Specific mobile subtypes are mapped to general 2G, 3G and 4G buckets.
  *
  * Logic is implemented as a state machine, so see the transition matrix to figure out what happens when.
  * This class depends on access to the context, so only use after GeckoAppShell has been initialized.
  */
 public class GeckoNetworkManager extends BroadcastReceiver implements BundleEventListener {
     private static final String LOGTAG = "GeckoNetworkManager";
 
+    // While gecko's network interfaces define this event, currently we do not use it.
+    // If network configuration and/or status changed, we send details of what changed.
+    // If we received a "check out new network state!" intent from the OS but nothing in it looks
+    // different, we ignore it. See Bug 1330836 for some relevant details.
     private static final String LINK_DATA_CHANGED = "changed";
 
     private static GeckoNetworkManager instance;
 
     // We hackishly (yet harmlessly, in this case) keep a Context reference passed in via the start method.
     // See context handling notes in handleManagerEvent, and Bug 1277333.
     private Context context;
 
@@ -316,18 +320,19 @@ public class GeckoNetworkManager extends
 
     @WrapForJNI(dispatchTo = "gecko")
     private static native void onStatusChanged(String status);
 
     /**
      * Send current network state and connection type to whomever is listening.
      */
     private void sendNetworkStateToListeners(final Context context) {
-        if (currentConnectionType != previousConnectionType ||
-                currentConnectionSubtype != previousConnectionSubtype) {
+        final boolean connectionTypeOrSubtypeChanged = currentConnectionType != previousConnectionType ||
+                currentConnectionSubtype != previousConnectionSubtype;
+        if (connectionTypeOrSubtypeChanged) {
             previousConnectionType = currentConnectionType;
             previousConnectionSubtype = currentConnectionSubtype;
 
             final boolean isWifi = currentConnectionType == ConnectionType.WIFI;
             final int gateway = !isWifi ? 0 :
                     wifiDhcpGatewayAddress(context);
 
             if (GeckoThread.isRunning()) {
@@ -336,30 +341,36 @@ public class GeckoNetworkManager extends
             } else {
                 GeckoThread.queueNativeCall(GeckoNetworkManager.class, "onConnectionChanged",
                                             currentConnectionType.value,
                                             String.class, currentConnectionSubtype.value,
                                             isWifi, gateway);
             }
         }
 
-        final String status;
-
-        if (currentNetworkStatus != previousNetworkStatus) {
-            previousNetworkStatus = currentNetworkStatus;
-            status = currentNetworkStatus.value;
-        } else {
-            status = LINK_DATA_CHANGED;
+        // If network configuration did not change and connection type, subtype and status are still
+        // the same, there's nothing to do. We choose to not send a "changed" notification in this case.
+        // See Bug 1330836 for relevant details.
+        if (currentNetworkStatus == previousNetworkStatus && !connectionTypeOrSubtypeChanged) {
+            return;
         }
 
+        previousNetworkStatus = currentNetworkStatus;
+
+        // Something changed, so send a "changed" status along with new network status state.
+        final String status = currentNetworkStatus.value;
+
         if (GeckoThread.isRunning()) {
+            onStatusChanged(LINK_DATA_CHANGED);
             onStatusChanged(status);
         } else {
             GeckoThread.queueNativeCall(GeckoNetworkManager.class, "onStatusChanged",
-                                        String.class, status);
+                    String.class, LINK_DATA_CHANGED);
+            GeckoThread.queueNativeCall(GeckoNetworkManager.class, "onStatusChanged",
+                    String.class, status);
         }
     }
 
     /**
      * Stop listening for network state updates.
      */
     private static void unregisterBroadcastReceiver(final Context context, final BroadcastReceiver receiver) {
         context.unregisterReceiver(receiver);