Bug 1250387 - Kill GckoConnectivityReceiver.java and improve GeckoNetworkManager.java r=grisha
authorShatur<tushar.saini1285@gmail.com>
Tue, 19 Apr 2016 06:31:17 +0530
changeset 331656 f2187390d83f57f18c70c643a36dc80ebfe08631
parent 331655 2a71ec431c13459a79d7c4ab222c8ef2cdacb9be
child 331657 9a55bb9bae73342d88a57ba0720a3711992db273
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgrisha
bugs1250387
milestone48.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 1250387 - Kill GckoConnectivityReceiver.java and improve GeckoNetworkManager.java r=grisha
mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
mobile/android/base/java/org/mozilla/gecko/GeckoConnectivityReceiver.java
mobile/android/base/java/org/mozilla/gecko/GeckoEvent.java
mobile/android/base/java/org/mozilla/gecko/GeckoNetworkManager.java
mobile/android/base/moz.build
widget/android/nsAppShell.cpp
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
@@ -117,29 +117,27 @@ public class GeckoApplication extends Ap
             final BrowserDB db = GeckoProfile.get(this).getDB();
             ThreadUtils.postToBackgroundThread(new Runnable() {
                 @Override
                 public void run() {
                     db.expireHistory(getContentResolver(), BrowserContract.ExpirePriority.NORMAL);
                 }
             });
         }
-        GeckoConnectivityReceiver.getInstance().stop();
         GeckoNetworkManager.getInstance().stop();
     }
 
     public void onActivityResume(GeckoActivityStatus activity) {
         if (mPausedGecko) {
             GeckoThread.onResume();
             mPausedGecko = false;
         }
 
         final Context applicationContext = getApplicationContext();
         GeckoBatteryManager.getInstance().start(applicationContext);
-        GeckoConnectivityReceiver.getInstance().start(applicationContext);
         GeckoNetworkManager.getInstance().start(applicationContext);
 
         mInBackground = false;
     }
 
     @Override
     public void onCreate() {
         Log.i(LOG_TAG, "zerdatime " + SystemClock.uptimeMillis() + " - Fennec application start");
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoConnectivityReceiver.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- 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 android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.util.Log;
-
-public class GeckoConnectivityReceiver extends BroadcastReceiver {
-    /*
-     * Keep the below constants in sync with
-     * http://mxr.mozilla.org/mozilla-central/source/netwerk/base/nsINetworkLinkService.idl
-     */
-    private static final String LINK_DATA_UP = "up";
-    private static final String LINK_DATA_DOWN = "down";
-    private static final String LINK_DATA_CHANGED = "changed";
-    private static final String LINK_DATA_UNKNOWN = "unknown";
-
-    private static final String LOGTAG = "GeckoConnectivityReceiver";
-
-    private static final GeckoConnectivityReceiver sInstance = new GeckoConnectivityReceiver();
-
-    private final IntentFilter mFilter;
-    private Context mApplicationContext;
-    private boolean mIsEnabled;
-
-    public static GeckoConnectivityReceiver getInstance() {
-        return sInstance;
-    }
-
-    private GeckoConnectivityReceiver() {
-        mFilter = new IntentFilter();
-        mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
-    }
-
-    public synchronized void start(Context context) {
-        if (mIsEnabled) {
-            Log.w(LOGTAG, "Already started!");
-            return;
-        }
-
-        mApplicationContext = context.getApplicationContext();
-
-        // registerReceiver will return null if registering fails.
-        if (mApplicationContext.registerReceiver(this, mFilter) == null) {
-            Log.e(LOGTAG, "Registering receiver failed");
-        } else {
-            mIsEnabled = true;
-        }
-    }
-
-    public synchronized void stop() {
-        if (!mIsEnabled) {
-            Log.w(LOGTAG, "Already stopped!");
-            return;
-        }
-
-        mApplicationContext.unregisterReceiver(this);
-        mApplicationContext = null;
-        mIsEnabled = false;
-    }
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
-        NetworkInfo info = cm.getActiveNetworkInfo();
-
-        final String status;
-        if (info == null) {
-            status = LINK_DATA_UNKNOWN;
-        } else if (!info.isConnected()) {
-            status = LINK_DATA_DOWN;
-        } else {
-            status = LINK_DATA_UP;
-        }
-
-        if (GeckoThread.isRunning()) {
-            GeckoAppShell.sendEventToGecko(GeckoEvent.createNetworkLinkChangeEvent(status));
-            GeckoAppShell.sendEventToGecko(GeckoEvent.createNetworkLinkChangeEvent(LINK_DATA_CHANGED));
-        }
-    }
-}
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoEvent.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoEvent.java
@@ -480,21 +480,22 @@ public class GeckoEvent {
     }
 
     public static GeckoEvent createVisitedEvent(String data) {
         GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.VISITED);
         event.mCharacters = data;
         return event;
     }
 
-    public static GeckoEvent createNetworkEvent(int connectionType, boolean isWifi, int DHCPGateway) {
+    public static GeckoEvent createNetworkEvent(int connectionType, boolean isWifi, int DHCPGateway, String status) {
         GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.NETWORK_CHANGED);
         event.mConnectionType = connectionType;
         event.mIsWifi = isWifi;
         event.mDHCPGateway = DHCPGateway;
+        event.mCharacters = status;
         return event;
     }
 
     public static GeckoEvent createThumbnailEvent(int tabId, int bufw, int bufh, ByteBuffer buffer) {
         GeckoEvent event = GeckoEvent.get(NativeGeckoEvent.THUMBNAIL);
         event.mPoints = new Point[1];
         event.mPoints[0] = new Point(bufw, bufh);
         event.mMetaState = tabId;
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoNetworkManager.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoNetworkManager.java
@@ -32,16 +32,32 @@ import android.util.Log;
  * exact network type, especially the cellular network type.
  *
  * Current connection is firstly obtained from Android's ConnectivityManager,
  * which is represented by the constant, and then will be mapped into the
  * connection type defined in Network Information API version 3.
  */
 
 public class GeckoNetworkManager extends BroadcastReceiver implements NativeEventListener {
+    /*
+     * Keep the below constants in sync with
+     * http://mxr.mozilla.org/mozilla-central/source/netwerk/base/nsINetworkLinkService.idl
+     */
+    private static final String LINK_DATA_UP = "up";
+    private static final String LINK_DATA_DOWN = "down";
+    private static final String LINK_DATA_CHANGED = "changed";
+    private static final String LINK_DATA_UNKNOWN = "unknown";
+
+    private static final String LINK_TYPE_UNKONWN = "unknown";
+    private static final String LINK_TYPE_ETHERNET = "ethernet";
+    private static final String LINK_TYPE_WIFI = "wifi";
+    private static final String LINK_TYPE_WIMAX = "wimax";
+    private static final String LINK_TYPE_2G = "2g";
+    private static final String LINK_TYPE_3G = "3g";
+    private static final String LINK_TYPE_4G = "4g";
     private static final String LOGTAG = "GeckoNetworkManager";
 
     private static GeckoNetworkManager sInstance;
 
     public static void destroy() {
         if (sInstance != null) {
             sInstance.onDestroy();
             sInstance = null;
@@ -102,16 +118,17 @@ public class GeckoNetworkManager extends
         }
 
         return sInstance;
     }
 
     @Override
     public void onReceive(Context aContext, Intent aIntent) {
         updateConnectionType();
+        updateLinkStatus(aContext);
     }
 
     public void start(final Context context) {
         // Note that this initialization clause only runs once.
         mApplicationContext = context.getApplicationContext();
         if (mConnectionType == ConnectionType.NONE) {
             mConnectionType = getConnectionType();
         }
@@ -250,17 +267,37 @@ public class GeckoNetworkManager extends
 
         if (!mShouldNotify) {
             return;
         }
 
         GeckoAppShell.sendEventToGecko(GeckoEvent.createNetworkEvent(
                                        newConnectionType.value,
                                        newConnectionType == ConnectionType.WIFI,
-                                       wifiDhcpGatewayAddress()));
+                                       wifiDhcpGatewayAddress(),
+                                       getConnectionSubType()));
+    }
+
+    public void updateLinkStatus(Context context) {
+        ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo info = cm.getActiveNetworkInfo();
+
+        final String status;
+        if (info == null) {
+            status = LINK_DATA_UNKNOWN;
+        } else if (!info.isConnected()) {
+            status = LINK_DATA_DOWN;
+        } else {
+            status = LINK_DATA_UP;
+        }
+
+        if (GeckoThread.isRunning()) {
+            GeckoAppShell.sendEventToGecko(GeckoEvent.createNetworkLinkChangeEvent(status));
+            GeckoAppShell.sendEventToGecko(GeckoEvent.createNetworkLinkChangeEvent(LINK_DATA_CHANGED));
+        }
     }
 
     public double[] getCurrentInformation() {
         final ConnectionType connectionType = mConnectionType;
         return new double[] { connectionType.value,
                               connectionType == ConnectionType.WIFI ? 1.0 : 0.0,
                               wifiDhcpGatewayAddress() };
     }
@@ -280,50 +317,103 @@ public class GeckoNetworkManager extends
     public void disableNotifications() {
         mShouldNotify = false;
 
         if (mShouldBeListening) {
             stopListening();
         }
     }
 
-    private ConnectionType getConnectionType() {
+    private NetworkInfo getConnectivityManager() {
         final Context appContext = mApplicationContext;
 
         if (null == appContext) {
-            return ConnectionType.NONE;
+          return null;
         }
 
         ConnectivityManager cm = (ConnectivityManager) appContext.getSystemService(Context.CONNECTIVITY_SERVICE);
         if (cm == null) {
-            Log.e(LOGTAG, "Connectivity service does not exist");
-            return ConnectionType.NONE;
+          Log.e(LOGTAG, "Connectivity service does not exist");
+          return null;
         }
 
         NetworkInfo ni = null;
         try {
             ni = cm.getActiveNetworkInfo();
-        } catch (SecurityException se) { /* if we don't have the permission, fall through to null check */ }
+        } catch (SecurityException se) {} // if we don't have the permission, fall through to null check
+
+        return ni;
+    }
+
+    private ConnectionType getConnectionType() {
+        NetworkInfo ni = getConnectivityManager();
+
         if (ni == null) {
             return ConnectionType.NONE;
         }
 
         switch (ni.getType()) {
-        case ConnectivityManager.TYPE_BLUETOOTH:
-            return ConnectionType.BLUETOOTH;
-        case ConnectivityManager.TYPE_ETHERNET:
-            return ConnectionType.ETHERNET;
-        case ConnectivityManager.TYPE_MOBILE:
-        case ConnectivityManager.TYPE_WIMAX:
-            return ConnectionType.CELLULAR;
-        case ConnectivityManager.TYPE_WIFI:
-            return ConnectionType.WIFI;
-        default:
-            Log.w(LOGTAG, "Ignoring the current network type.");
-            return ConnectionType.OTHER;
+            case ConnectivityManager.TYPE_BLUETOOTH:
+                return ConnectionType.BLUETOOTH;
+            case ConnectivityManager.TYPE_ETHERNET:
+                return ConnectionType.ETHERNET;
+            case ConnectivityManager.TYPE_MOBILE:
+            case ConnectivityManager.TYPE_WIMAX:
+                return ConnectionType.CELLULAR;
+            case ConnectivityManager.TYPE_WIFI:
+                return ConnectionType.WIFI;
+            default:
+                Log.w(LOGTAG, "Ignoring the current network type.");
+                return ConnectionType.OTHER;
+        }
+    }
+
+    private String getConnectionSubType() {
+        NetworkInfo ni = getConnectivityManager();
+
+        if (ni == null) {
+            return LINK_TYPE_UNKONWN;
+        }
+
+        switch (ni.getType()) {
+            case ConnectivityManager.TYPE_ETHERNET:
+                return LINK_TYPE_ETHERNET;
+            case ConnectivityManager.TYPE_MOBILE:
+                switch (ni.getSubtype()) {
+                    case TelephonyManager.NETWORK_TYPE_GPRS:
+                    case TelephonyManager.NETWORK_TYPE_EDGE:
+                    case TelephonyManager.NETWORK_TYPE_CDMA:
+                    case TelephonyManager.NETWORK_TYPE_1xRTT:
+                    case TelephonyManager.NETWORK_TYPE_IDEN:
+                        return LINK_TYPE_2G;
+                    case TelephonyManager.NETWORK_TYPE_UMTS:
+                    case TelephonyManager.NETWORK_TYPE_EVDO_0:
+                    case TelephonyManager.NETWORK_TYPE_EVDO_A:
+                    case TelephonyManager.NETWORK_TYPE_HSDPA:
+                    case TelephonyManager.NETWORK_TYPE_HSUPA:
+                    case TelephonyManager.NETWORK_TYPE_HSPA:
+                    case TelephonyManager.NETWORK_TYPE_EVDO_B:
+                    case TelephonyManager.NETWORK_TYPE_EHRPD:
+                    case TelephonyManager.NETWORK_TYPE_HSPAP:
+                        return LINK_TYPE_3G;
+                    case TelephonyManager.NETWORK_TYPE_LTE:
+                        return LINK_TYPE_4G;
+                    default:
+                        return LINK_TYPE_2G;
+                    /* We are not returning LINK_TYPE_UNKONOWN because we treat unknown
+                     * as "no connection" in code elsewhere, which is not the case.
+                     * TODO: Network change notification issue causes a caching problem (Bug 1236130).
+                     */
+                }
+            case ConnectivityManager.TYPE_WIMAX:
+                return LINK_TYPE_WIMAX;
+            case ConnectivityManager.TYPE_WIFI:
+                return LINK_TYPE_WIFI;
+            default:
+                return LINK_TYPE_UNKONWN;
         }
     }
 
     private static int getNetworkOperator(InfoType type, Context context) {
         if (null == context) {
             return -1;
         }
 
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -309,17 +309,16 @@ gbjar.sources += ['java/org/mozilla/geck
     'FormAssistPopup.java',
     'GeckoAccessibility.java',
     'GeckoActivity.java',
     'GeckoActivityStatus.java',
     'GeckoApp.java',
     'GeckoApplication.java',
     'GeckoAppShell.java',
     'GeckoBatteryManager.java',
-    'GeckoConnectivityReceiver.java',
     'GeckoEditable.java',
     'GeckoEditableClient.java',
     'GeckoEditableListener.java',
     'GeckoEvent.java',
     'GeckoHalDefines.java',
     'GeckoInputConnection.java',
     'GeckoJavaSampler.java',
     'GeckoMessageReceiver.java',
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -827,16 +827,22 @@ nsAppShell::LegacyGeckoEvent::Run()
 #endif
         break;
     }
 
     case AndroidGeckoEvent::NETWORK_CHANGED: {
         hal::NotifyNetworkChange(hal::NetworkInformation(curEvent->ConnectionType(),
                                                          curEvent->IsWifi(),
                                                          curEvent->DHCPGateway()));
+        nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+        if (os) {
+            os->NotifyObservers(nullptr,
+                                NS_NETWORK_LINK_TYPE_TOPIC,
+                                nsString(curEvent->Characters()).get());
+        }
         break;
     }
 
     case AndroidGeckoEvent::SCREENORIENTATION_CHANGED: {
         nsresult rv;
         nsCOMPtr<nsIScreenManager> screenMgr =
             do_GetService("@mozilla.org/gfx/screenmanager;1", &rv);
         if (NS_FAILED(rv)) {