am 59ea2612: am 53e52e52: Merge "SysUI: Add basic test coverage for signal levels" into lmp-mr1-dev

* commit '59ea2612d41d735ae7a6fb9cb485e1405224336e':
  SysUI: Add basic test coverage for signal levels
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 9cfd26b..0caded5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -177,12 +177,21 @@
      * Construct this controller object and register for updates.
      */
     public NetworkControllerImpl(Context context) {
+        this(context, (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE),
+                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
+                (WifiManager) context.getSystemService(Context.WIFI_SERVICE));
+        registerListeners();
+    }
+
+    @VisibleForTesting
+    NetworkControllerImpl(Context context, ConnectivityManager connectivityManager,
+            TelephonyManager telephonyManager, WifiManager wifiManager) {
         mContext = context;
         final Resources res = context.getResources();
 
-        mConnectivityManager =
-                (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-        mHasMobileDataFeature = getCM().isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+        mConnectivityManager = connectivityManager;
+        mHasMobileDataFeature =
+                mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
 
         mShowPhoneRSSIForData = res.getBoolean(R.bool.config_showPhoneRSSIForData);
         mShowAtLeastThreeGees = res.getBoolean(R.bool.config_showMin3G);
@@ -203,7 +212,7 @@
         mNetworkName = mNetworkNameDefault;
 
         // wifi
-        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+        mWifiManager = wifiManager;
         Handler handler = new WifiHandler();
         mWifiChannel = new AsyncChannel();
         Messenger wifiMessenger = mWifiManager.getWifiServiceMessenger();
@@ -211,8 +220,6 @@
             mWifiChannel.connect(mContext, handler, wifiMessenger);
         }
 
-        registerListeners();
-
         // AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
         updateAirplaneMode();
 
@@ -227,13 +234,7 @@
         });
     }
 
-    @VisibleForTesting
-    protected ConnectivityManager getCM() {
-        return mConnectivityManager;
-    }
-
-    @VisibleForTesting
-    protected void registerListeners() {
+    private void registerListeners() {
         mPhone.listen(mPhoneStateListener,
                           PhoneStateListener.LISTEN_SERVICE_STATE
                         | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
@@ -1085,7 +1086,7 @@
             Log.d(TAG, "updateConnectivity: intent=" + intent);
         }
 
-        final NetworkInfo info = getCM().getActiveNetworkInfo();
+        final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
 
         // Are we connected at all, by any interface?
         mConnected = info != null && info.isConnected();
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index 262e071..8b87522 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -19,7 +19,7 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
 
 LOCAL_PACKAGE_NAME := SystemUITests
 LOCAL_INSTRUMENTATION_FOR := SystemUI
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index c0aa31d..97605ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -4,16 +4,19 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import android.content.Context;
 import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
+import android.net.wifi.WifiManager;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import com.android.internal.telephony.cdma.EriInfo;
+import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
 import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster;
 
 import org.mockito.ArgumentCaptor;
@@ -24,13 +27,23 @@
 
 public class NetworkControllerBaseTest extends AndroidTestCase {
     private static final String TAG = "NetworkControllerBaseTest";
+    protected static final int DEFAULT_LEVEL = 2;
+    protected static final int DEFAULT_SIGNAL_STRENGTH =
+            TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][DEFAULT_LEVEL];
+    protected static final int DEFAULT_QS_SIGNAL_STRENGTH =
+            TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][DEFAULT_LEVEL];
+    protected static final int DEFAULT_ICON = TelephonyIcons.ICON_3G;
+    protected static final int DEFAULT_QS_ICON = TelephonyIcons.QS_ICON_3G;
 
     protected NetworkControllerImpl mNetworkController;
     protected PhoneStateListener mPhoneStateListener;
     protected SignalCluster mSignalCluster;
+    protected NetworkSignalChangedCallback mNetworkSignalChangedCallback;
     private SignalStrength mSignalStrength;
     private ServiceState mServiceState;
-    private ConnectivityManager mMockCM;
+    protected ConnectivityManager mMockCm;
+    protected WifiManager mMockWm;
+    protected TelephonyManager mMockTm;
 
     @Override
     protected void setUp() throws Exception {
@@ -39,17 +52,24 @@
         System.setProperty("dexmaker.dexcache", mContext.getCacheDir().getPath());
         Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
 
-        mMockCM = mock(ConnectivityManager.class);
-        when(mMockCM.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true);
+        mMockWm = mock(WifiManager.class);
+        mMockTm = mock(TelephonyManager.class);
+        mMockCm = mock(ConnectivityManager.class);
+        when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true);
 
-        // TODO: Move away from fake, use spy if possible after MSIM refactor.
-        mNetworkController = new FakeNetworkControllerImpl(mContext);
-
-        mPhoneStateListener = mNetworkController.mPhoneStateListener;
         mSignalStrength = mock(SignalStrength.class);
         mServiceState = mock(ServiceState.class);
         mSignalCluster = mock(SignalCluster.class);
+        mNetworkSignalChangedCallback = mock(NetworkSignalChangedCallback.class);
+
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm);
+        setupNetworkController();
+    }
+
+    protected void setupNetworkController() {
+        mPhoneStateListener = mNetworkController.mPhoneStateListener;
         mNetworkController.addSignalCluster(mSignalCluster);
+        mNetworkController.addNetworkSignalChangedCallback(mNetworkSignalChangedCallback);
     }
 
     @Override
@@ -62,13 +82,24 @@
         super.tearDown();
     }
 
+    // 2 Bars 3G GSM.
+    public void setupDefaultSignal() {
+        setIsGsm(true);
+        setVoiceRegState(ServiceState.STATE_IN_SERVICE);
+        setGsmRoaming(false);
+        setLevel(DEFAULT_LEVEL);
+        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_UMTS);
+        setConnectivity(100, ConnectivityManager.TYPE_MOBILE, true);
+    }
+
     public void setConnectivity(int inetCondition, int networkType, boolean isConnected) {
         Intent i = new Intent(ConnectivityManager.INET_CONDITION_ACTION);
         NetworkInfo networkInfo = mock(NetworkInfo.class);
         when(networkInfo.isConnected()).thenReturn(isConnected);
         when(networkInfo.getType()).thenReturn(networkType);
         when(networkInfo.getTypeName()).thenReturn("");
-        when(mMockCM.getActiveNetworkInfo()).thenReturn(networkInfo);
+        when(mMockCm.getActiveNetworkInfo()).thenReturn(networkInfo);
 
         i.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, inetCondition);
         mNetworkController.onReceive(mContext, i);
@@ -79,11 +110,24 @@
         updateServiceState();
     }
 
+    public void setCdmaRoaming(boolean isRoaming) {
+        when(mServiceState.getCdmaEriIconIndex()).thenReturn(isRoaming ?
+                EriInfo.ROAMING_INDICATOR_ON : EriInfo.ROAMING_INDICATOR_OFF);
+        when(mServiceState.getCdmaEriIconMode()).thenReturn(isRoaming ?
+                EriInfo.ROAMING_ICON_MODE_NORMAL : -1);
+        updateServiceState();
+    }
+
     public void setVoiceRegState(int voiceRegState) {
         when(mServiceState.getVoiceRegState()).thenReturn(voiceRegState);
         updateServiceState();
     }
 
+    public void setDataRegState(int dataRegState) {
+        when(mServiceState.getDataRegState()).thenReturn(dataRegState);
+        updateServiceState();
+    }
+
     public void setIsEmergencyOnly(boolean isEmergency) {
         when(mServiceState.isEmergencyOnly()).thenReturn(isEmergency);
         updateServiceState();
@@ -131,32 +175,49 @@
         mPhoneStateListener.onDataActivity(dataActivity);
     }
 
-    protected void verifyLastMobileDataIndicators(boolean visible, int icon) {
+    protected void verifyLastQsMobileDataIndicators(boolean visible, int icon, int typeIcon,
+            boolean dataIn, boolean dataOut, boolean noSim) {
         ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class);
+        ArgumentCaptor<Boolean> dataInArg = ArgumentCaptor.forClass(Boolean.class);
+        ArgumentCaptor<Boolean> dataOutArg = ArgumentCaptor.forClass(Boolean.class);
+        ArgumentCaptor<Boolean> noSimArg = ArgumentCaptor.forClass(Boolean.class);
+
+        Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce())
+                .onMobileDataSignalChanged(visibleArg.capture(), iconArg.capture(),
+                        ArgumentCaptor.forClass(String.class).capture(),
+                        typeIconArg.capture(),
+                        dataInArg.capture(),
+                        dataOutArg.capture(),
+                        ArgumentCaptor.forClass(String.class).capture(),
+                        ArgumentCaptor.forClass(String.class).capture(),
+                        noSimArg.capture(),
+                        ArgumentCaptor.forClass(Boolean.class).capture());
+        assertEquals("Visibility in, quick settings", visible, (boolean) visibleArg.getValue());
+        assertEquals("Signal icon in, quick settings", icon, (int) iconArg.getValue());
+        assertEquals("Data icon in, quick settings", typeIcon, (int) typeIconArg.getValue());
+        assertEquals("Data direction in, in quick settings", dataIn,
+                (boolean) dataInArg.getValue());
+        assertEquals("Data direction out, in quick settings", dataOut,
+                (boolean) dataOutArg.getValue());
+        assertEquals("Sim state in quick settings", noSim, (boolean) noSimArg.getValue());
+    }
+
+    protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon) {
+        ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
         ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class);
 
         // TODO: Verify all fields.
         Mockito.verify(mSignalCluster, Mockito.atLeastOnce()).setMobileDataIndicators(
-                visibleArg.capture(), iconArg.capture(),
-                ArgumentCaptor.forClass(Integer.class).capture(),
+                visibleArg.capture(), iconArg.capture(), typeIconArg.capture(),
                 ArgumentCaptor.forClass(String.class).capture(),
                 ArgumentCaptor.forClass(String.class).capture(),
                 ArgumentCaptor.forClass(Boolean.class).capture());
 
-        assertEquals(icon, (int) iconArg.getValue());
-        assertEquals(visible, (boolean) visibleArg.getValue());
-    }
-
-    private class FakeNetworkControllerImpl extends NetworkControllerImpl {
-        public FakeNetworkControllerImpl(Context context) {
-            super(context);
-        }
-
-        @Override
-        public ConnectivityManager getCM() {
-            return mMockCM;
-        }
-
-        public void registerListeners() {};
+        assertEquals("Signal icon in status bar", icon, (int) iconArg.getValue());
+        assertEquals("Data icon in status bar", typeIcon, (int) typeIconArg.getValue());
+        assertEquals("Visibility in status bar", visible, (boolean) visibleArg.getValue());
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
new file mode 100644
index 0000000..146e76d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -0,0 +1,99 @@
+package com.android.systemui.statusbar.policy;
+
+import android.telephony.TelephonyManager;
+
+// WARNING: Many of these tests may fail with config showMin3G.
+// TODO: Maybe fix the above.
+public class NetworkControllerDataTest extends NetworkControllerBaseTest {
+
+    public void test3gDataIcon() {
+        setupDefaultSignal();
+
+        verifyDataIndicators(TelephonyIcons.DATA_3G[1][0 /* No direction */],
+                TelephonyIcons.QS_DATA_3G[1]);
+    }
+
+    public void testRoamingDataIcon() {
+        setupDefaultSignal();
+        setGsmRoaming(true);
+
+        verifyLastMobileDataIndicators(true,
+                TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][DEFAULT_LEVEL],
+                TelephonyIcons.ROAMING_ICON);
+        verifyLastQsMobileDataIndicators(true,
+                TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][DEFAULT_LEVEL],
+                TelephonyIcons.QS_DATA_R[1], false, false, false);
+    }
+
+    public void test2gDataIcon() {
+        setupDefaultSignal();
+        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_GSM);
+
+        verifyDataIndicators(TelephonyIcons.DATA_G[1][0 /* No direction */],
+                TelephonyIcons.QS_DATA_G[1]);
+    }
+
+    public void testCdmaDataIcon() {
+        setupDefaultSignal();
+        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_CDMA);
+
+        verifyDataIndicators(TelephonyIcons.DATA_1X[1][0 /* No direction */],
+                TelephonyIcons.QS_DATA_1X[1]);
+    }
+
+    public void testEdgeDataIcon() {
+        setupDefaultSignal();
+        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_EDGE);
+
+        verifyDataIndicators(TelephonyIcons.DATA_E[1][0 /* No direction */],
+                TelephonyIcons.QS_DATA_E[1]);
+    }
+
+    public void testLteDataIcon() {
+        setupDefaultSignal();
+        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_LTE);
+
+        // WARNING: May fail depending on config.
+        verifyDataIndicators(TelephonyIcons.DATA_LTE[1][0 /* No direction */],
+                TelephonyIcons.QS_DATA_LTE[1]);
+    }
+
+    public void testHspaDataIcon() {
+        setupDefaultSignal();
+        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_HSPA);
+
+        // WARNING: May fail depending on config.
+        verifyDataIndicators(TelephonyIcons.DATA_H[1][0 /* No direction */],
+                TelephonyIcons.QS_DATA_H[1]);
+    }
+
+    public void testDataActivity() {
+        setupDefaultSignal();
+
+        testDataActivity(TelephonyManager.DATA_ACTIVITY_NONE, false, false);
+        testDataActivity(TelephonyManager.DATA_ACTIVITY_IN, true, false);
+        testDataActivity(TelephonyManager.DATA_ACTIVITY_OUT, false, true);
+        testDataActivity(TelephonyManager.DATA_ACTIVITY_INOUT, true, true);
+    }
+
+    private void testDataActivity(int direction, boolean in, boolean out) {
+        updateDataActivity(direction);
+
+        verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, DEFAULT_ICON);
+        verifyLastQsMobileDataIndicators(true, DEFAULT_QS_SIGNAL_STRENGTH,
+                DEFAULT_QS_ICON, in, out, false);
+
+    }
+
+    private void verifyDataIndicators(int dataIcon, int qsDataIcon) {
+        verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, dataIcon);
+        verifyLastQsMobileDataIndicators(true, DEFAULT_QS_SIGNAL_STRENGTH, qsDataIcon, false,
+                false, false);
+    }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index fc2b1aa..ed76ae5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -5,33 +5,122 @@
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
 
+import com.android.systemui.R;
+
+import org.mockito.Mockito;
+
 public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
 
-    public void testSignalStrength() {
-        int testStrength = SignalStrength.SIGNAL_STRENGTH_MODERATE;
-        setIsGsm(true);
-        setVoiceRegState(ServiceState.STATE_IN_SERVICE);
-        setGsmRoaming(false);
-        setLevel(testStrength);
-        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
-                TelephonyManager.NETWORK_TYPE_UMTS);
-        setConnectivity(100, ConnectivityManager.TYPE_MOBILE, true);
+    public void testNoIconWithoutMobile() {
+        // Turn off mobile network support.
+        Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
+        // Create a new NetworkController as this is currently handled in constructor.
+        mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm);
+        setupNetworkController();
 
-        verifyLastMobileDataIndicators(true,
-                TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][testStrength]);
+        verifyLastMobileDataIndicators(false, 0, 0);
+    }
+
+    public void testSignalStrength() {
+        for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+                testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
+            setupDefaultSignal();
+            setLevel(testStrength);
+
+            verifyLastMobileDataIndicators(true,
+                    TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][testStrength],
+                    DEFAULT_ICON);
+
+            // Verify low inet number indexing.
+            setConnectivity(10, ConnectivityManager.TYPE_MOBILE, true);
+            verifyLastMobileDataIndicators(true,
+                    TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[0][testStrength], 0);
+        }
+    }
+
+    public void testCdmaSignalStrength() {
+        for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+                testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
+            setupDefaultSignal();
+            setCdma();
+            setLevel(testStrength);
+
+            verifyLastMobileDataIndicators(true,
+                    TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][testStrength],
+                    TelephonyIcons.DATA_1X[1][0 /* No direction */]);
+        }
     }
 
     public void testSignalRoaming() {
-        int testStrength = SignalStrength.SIGNAL_STRENGTH_MODERATE;
-        setIsGsm(true);
-        setVoiceRegState(ServiceState.STATE_IN_SERVICE);
-        setGsmRoaming(true);
-        setLevel(testStrength);
-        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
-                TelephonyManager.NETWORK_TYPE_UMTS);
-        setConnectivity(100, ConnectivityManager.TYPE_MOBILE, true);
+        for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+                testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
+            setupDefaultSignal();
+            setGsmRoaming(true);
+            setLevel(testStrength);
 
-        verifyLastMobileDataIndicators(true,
-                TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][testStrength]);
+            verifyLastMobileDataIndicators(true,
+                    TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][testStrength],
+                    TelephonyIcons.ROAMING_ICON);
+        }
+    }
+
+    public void testCdmaSignalRoaming() {
+        for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+                testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
+            setupDefaultSignal();
+            setCdma();
+            setCdmaRoaming(true);
+            setLevel(testStrength);
+
+            verifyLastMobileDataIndicators(true,
+                    TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][testStrength],
+                    TelephonyIcons.ROAMING_ICON);
+        }
+    }
+
+    public void testQsSignalStrength() {
+        for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+                testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
+            setupDefaultSignal();
+            setLevel(testStrength);
+
+            verifyLastQsMobileDataIndicators(true,
+                    TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][testStrength],
+                    DEFAULT_QS_ICON, false, false, false);
+        }
+    }
+
+    public void testCdmaQsSignalStrength() {
+        for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+                testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
+            setupDefaultSignal();
+            setCdma();
+            setLevel(testStrength);
+
+            verifyLastQsMobileDataIndicators(true,
+                    TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][testStrength],
+                    TelephonyIcons.QS_ICON_1X, false, false, false);
+        }
+    }
+
+    public void testNoRoamingWithoutSignal() {
+        setupDefaultSignal();
+        setCdma();
+        setCdmaRoaming(true);
+        setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE);
+        setDataRegState(ServiceState.STATE_OUT_OF_SERVICE);
+
+        // This exposes the bug in b/18034542, and should be switched to the commented out
+        // verification below (and pass), once the bug is fixed.
+        verifyLastMobileDataIndicators(true, R.drawable.stat_sys_signal_null,
+                TelephonyIcons.ROAMING_ICON);
+        //verifyLastMobileDataIndicators(true, R.drawable.stat_sys_signal_null, 0 /* No Icon */);
+    }
+
+    private void setCdma() {
+        setIsGsm(false);
+        updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+                TelephonyManager.NETWORK_TYPE_CDMA);
+        setCdmaRoaming(false);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
new file mode 100644
index 0000000..4ffdff2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -0,0 +1,201 @@
+package com.android.systemui.statusbar.policy;
+
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+
+import com.android.systemui.R;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
+public class NetworkControllerWifiTest extends NetworkControllerBaseTest {
+    // These match the constants in WifiManager and need to be kept up to date.
+    private static final int MIN_RSSI = -100;
+    private static final int MAX_RSSI = -55;
+
+    // TODO: Move this into WifiIcons, remove all R.drawable from NetworkControllerImpl.
+    private static final int NULL_SIGNAL = R.drawable.stat_sys_wifi_signal_null;
+    private static final int QS_NO_NET = R.drawable.ic_qs_wifi_no_network;
+
+    public void testWifiIcon() {
+        String testSsid = "Test SSID";
+        setWifiEnabled(true);
+        verifyLastWifiIcon(false, NULL_SIGNAL);
+
+        setWifiState(true, testSsid);
+        verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[0][0]);
+
+        for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
+            setWifiLevel(testLevel);
+
+            setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
+            verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
+            setConnectivity(10, ConnectivityManager.TYPE_WIFI, true);
+            verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[0][testLevel]);
+        }
+    }
+
+    public void testQsWifiIcon() {
+        String testSsid = "Test SSID";
+
+        setWifiEnabled(false);
+        verifyLastQsWifiIcon(false, false, 0, null);
+
+        setWifiEnabled(true);
+        verifyLastQsWifiIcon(true, false, QS_NO_NET, null);
+
+        setWifiState(true, testSsid);
+        for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
+            setWifiLevel(testLevel);
+
+            setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
+            verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[1][testLevel],
+                    testSsid);
+            setConnectivity(10, ConnectivityManager.TYPE_WIFI, true);
+            verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[0][testLevel],
+                    testSsid);
+        }
+    }
+
+    public void testQsDataDirection() {
+        // Setup normal connection
+        String testSsid = "Test SSID";
+        int testLevel = 2;
+        setWifiEnabled(true);
+        setWifiState(true, testSsid);
+        setWifiLevel(testLevel);
+        setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
+        verifyLastQsWifiIcon(true, true,
+                WifiIcons.QS_WIFI_SIGNAL_STRENGTH[1][testLevel], testSsid);
+
+        setWifiActivity(WifiManager.DATA_ACTIVITY_NONE);
+        verifyLastQsDataDirection(false, false);
+        setWifiActivity(WifiManager.DATA_ACTIVITY_IN);
+        verifyLastQsDataDirection(true, false);
+        setWifiActivity(WifiManager.DATA_ACTIVITY_OUT);
+        verifyLastQsDataDirection(false, true);
+        setWifiActivity(WifiManager.DATA_ACTIVITY_INOUT);
+        verifyLastQsDataDirection(true, true);
+    }
+
+    public void testNoDataIconDuringWifi() {
+        // Setup normal connection
+        String testSsid = "Test SSID";
+        int testLevel = 2;
+        setWifiEnabled(true);
+        setWifiState(true, testSsid);
+        setWifiLevel(testLevel);
+        setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
+        verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
+
+        setupDefaultSignal();
+        // Still be on wifi though.
+        setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
+        verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, 0 /* No icon */);
+    }
+
+    public void testRoamingIconDuringWifi() {
+        // Setup normal connection
+        String testSsid = "Test SSID";
+        int testLevel = 2;
+        setWifiEnabled(true);
+        setWifiState(true, testSsid);
+        setWifiLevel(testLevel);
+        setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
+        verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
+
+        setupDefaultSignal();
+        setGsmRoaming(true);
+        // Still be on wifi though.
+        setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
+        verifyLastMobileDataIndicators(true,
+                TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][DEFAULT_LEVEL],
+                TelephonyIcons.ROAMING_ICON);
+    }
+
+    protected void setWifiActivity(int activity) {
+        // TODO: Not this, because this variable probably isn't sticking around.
+        mNetworkController.mWifiActivity = activity;
+        mNetworkController.refreshViews();
+    }
+
+    protected void setWifiLevel(int level) {
+        float amountPerLevel = (MAX_RSSI - MIN_RSSI) / (WifiIcons.WIFI_LEVEL_COUNT - 1);
+        int rssi = (int)(MIN_RSSI + level * amountPerLevel);
+        // Put RSSI in the middle of the range.
+        rssi += amountPerLevel / 2;
+        Intent i = new Intent(WifiManager.RSSI_CHANGED_ACTION);
+        i.putExtra(WifiManager.EXTRA_NEW_RSSI, rssi);
+        mNetworkController.onReceive(mContext, i);
+    }
+
+    protected void setWifiEnabled(boolean enabled) {
+        Intent i = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
+        i.putExtra(WifiManager.EXTRA_WIFI_STATE,
+                enabled ? WifiManager.WIFI_STATE_ENABLED : WifiManager.WIFI_STATE_DISABLED);
+        mNetworkController.onReceive(mContext, i);
+    }
+
+    protected void setWifiState(boolean connected, String ssid) {
+        Intent i = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        NetworkInfo networkInfo = Mockito.mock(NetworkInfo.class);
+        Mockito.when(networkInfo.isConnected()).thenReturn(connected);
+
+        WifiInfo wifiInfo = Mockito.mock(WifiInfo.class);
+        Mockito.when(wifiInfo.getSSID()).thenReturn(ssid);
+
+        i.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
+        i.putExtra(WifiManager.EXTRA_WIFI_INFO, wifiInfo);
+        mNetworkController.onReceive(mContext, i);
+    }
+
+    protected void verifyLastQsDataDirection(boolean in, boolean out) {
+        ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class);
+        ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class);
+
+        Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce()).onWifiSignalChanged(
+                ArgumentCaptor.forClass(Boolean.class).capture(),
+                ArgumentCaptor.forClass(Boolean.class).capture(),
+                ArgumentCaptor.forClass(Integer.class).capture(),
+                inArg.capture(), outArg.capture(),
+                ArgumentCaptor.forClass(String.class).capture(),
+                ArgumentCaptor.forClass(String.class).capture());
+        assertEquals("WiFi data in, in quick settings", in, (boolean) inArg.getValue());
+        assertEquals("WiFi data out, in quick settings", out, (boolean) outArg.getValue());
+    }
+
+    protected void verifyLastQsWifiIcon(boolean enabled, boolean connected, int icon,
+            String description) {
+        ArgumentCaptor<Boolean> enabledArg = ArgumentCaptor.forClass(Boolean.class);
+        ArgumentCaptor<Boolean> connectedArg = ArgumentCaptor.forClass(Boolean.class);
+        ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class);
+
+        Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce()).onWifiSignalChanged(
+                enabledArg.capture(), connectedArg.capture(), iconArg.capture(),
+                ArgumentCaptor.forClass(Boolean.class).capture(),
+                ArgumentCaptor.forClass(Boolean.class).capture(),
+                ArgumentCaptor.forClass(String.class).capture(),
+                descArg.capture());
+        assertEquals("WiFi enabled, in quick settings", enabled, (boolean) enabledArg.getValue());
+        assertEquals("WiFi connected, in quick settings", connected,
+                (boolean) connectedArg.getValue());
+        assertEquals("WiFi signal, in quick settings", icon, (int) iconArg.getValue());
+        assertEquals("WiFI desc (ssid), in quick settings", description,
+                (String) descArg.getValue());
+    }
+
+    protected void verifyLastWifiIcon(boolean visible, int icon) {
+        ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class);
+        ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class);
+
+        Mockito.verify(mSignalCluster, Mockito.atLeastOnce()).setWifiIndicators(
+                visibleArg.capture(), iconArg.capture(),
+                ArgumentCaptor.forClass(String.class).capture());
+        assertEquals("WiFi visible, in status bar", visible, (boolean) visibleArg.getValue());
+        assertEquals("WiFi signal, in status bar", icon, (int) iconArg.getValue());
+    }
+}