OSDN Git Service

Merge "Correct detail page UI once user change MAC randomized setting" into qt-dev
authorClown SHEN <clownshen@google.com>
Tue, 23 Apr 2019 03:01:48 +0000 (03:01 +0000)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Tue, 23 Apr 2019 03:01:48 +0000 (03:01 +0000)
src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java

index ae96ed3..eaf3678 100644 (file)
@@ -146,7 +146,8 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
     private static final long TIMEOUT = Duration.ofSeconds(10).toMillis();
 
     // Be static to avoid too much object not be reset.
-    private static CountDownTimer mTimer;
+    @VisibleForTesting
+    static CountDownTimer mTimer;
 
     private AccessPoint mAccessPoint;
     private final ConnectivityManager mConnectivityManager;
@@ -256,20 +257,15 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
 
         @Override
         public void onLost(Network network) {
-            final boolean lostCurrentNetwork = network.equals(mNetwork);
-            if (lostCurrentNetwork) {
-                // Should update as disconnect but not exit. Except for ephemeral network which
-                // should not show on saved network list.
-                if (!mIsEphemeral) {
-                    return;
-                }
-
+            // Ephemeral network not a saved network, leave detail page once disconnected
+            if (mIsEphemeral && network.equals(mNetwork)) {
                 exitActivity();
             }
         }
     };
 
-    private final WifiTracker.WifiListener mWifiListener = new WifiTracker.WifiListener() {
+    @VisibleForTesting
+    final WifiTracker.WifiListener mWifiListener = new WifiTracker.WifiListener() {
         /** Called when the state of Wifi has changed. */
         public void onWifiStateChanged(int state) {
             Log.d(TAG, "onWifiStateChanged(" + state + ")");
@@ -284,16 +280,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
 
         /** Called when the connection state of wifi has changed. */
         public void onConnectedChanged() {
-            updateAccessPointFromScannedList();
-            if (mConnected != mAccessPoint.isActive()) {
-                Log.d(TAG, "Connection state changed!");
-                mConnected = mAccessPoint.isActive();
-                if (mAccessPoint.isActive()) {
-                    updateConnectingState(STATE_CONNECTED);
-                } else {
-                    updateConnectingState(STATE_DISCONNECTED);
-                }
-            }
+            refreshPage();
         }
 
         /**
@@ -516,42 +503,41 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
         refreshMacAddress();
     }
 
-    private boolean updateAccessPoint() {
+    @VisibleForTesting
+    boolean updateAccessPoint() {
         boolean changed = false;
-        if (mWifiTracker != null) {
-            // remember mIsOutOfRange as old before updated
-            boolean oldState = mIsOutOfRange;
-            updateAccessPointFromScannedList();
-            // refresh UI if signal level changed for disconnect network.
-            changed = mRssiSignalLevel != mAccessPoint.getLevel();
-            changed |= oldState != mIsOutOfRange;
-        }
+        // remember mIsOutOfRange as old before updated
+        boolean oldState = mIsOutOfRange;
+        updateAccessPointFromScannedList();
 
         if (mAccessPoint.isActive()) {
-            // Sometimes {@link WifiManager#getCurrentNetwork()} return null after connected,
-            // refresh it if needed.
-            if (mNetwork == null) {
-                updateNetworkInfo();
-            }
+            updateNetworkInfo();
             mNetworkInfo = mConnectivityManager.getNetworkInfo(mNetwork);
             mWifiInfo = mWifiManager.getConnectionInfo();
             if (mNetwork == null || mNetworkInfo == null || mWifiInfo == null) {
-                // Once connected, can't get mNetworkInfo immediately, return false and wait for
-                // next time to update UI.
+                // Once connected, can't get mNetwork immediately, return false and wait for
+                // next time to update UI. also reset {@code mIsOutOfRange}
+                mIsOutOfRange = oldState;
                 return false;
             }
-
             changed |= mAccessPoint.update(mWifiConfig, mWifiInfo, mNetworkInfo);
-            // If feature for saved network not enabled, always return true.
-            return mWifiTracker == null || changed;
+        }
+
+        // signal level changed
+        changed |= mRssiSignalLevel != mAccessPoint.getLevel();
+        // In/Out of range changed
+        changed |= oldState != mIsOutOfRange;
+        // connect state changed
+        if (mConnected != mAccessPoint.isActive()) {
+            mConnected = mAccessPoint.isActive();
+            changed = true;
+            updateConnectingState(mAccessPoint.isActive() ? STATE_CONNECTED : STATE_DISCONNECTED);
         }
 
         return changed;
     }
 
     private void updateAccessPointFromScannedList() {
-        if (mWifiTracker == null) return;
-
         mIsOutOfRange = true;
 
         for (AccessPoint ap : mWifiTracker.getAccessPoints()) {
@@ -967,7 +953,8 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
         return FeatureFlagUtils.isEnabled(context, FeatureFlags.WIFI_DETAILS_DATAUSAGE_HEADER);
     }
 
-    private void connectNetwork() {
+    @VisibleForTesting
+    void connectNetwork() {
         final Activity activity = mFragment.getActivity();
         // error handling, connected/saved network should have mWifiConfig.
         if (mWifiConfig == null) {
@@ -1045,7 +1032,6 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
                                     mAccessPoint.getTitle()),
                             Toast.LENGTH_SHORT).show();
 
-                    updateNetworkInfo();
                     refreshPage();
                 } else if (state == STATE_NOT_IN_RANGE) {
                     Log.d(TAG, "AP not in range");
@@ -1084,7 +1070,11 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
                         .setButton3Enabled(false);
                 break;
             case STATE_CONNECTED:
-                mButtonsPref.setButton3Visible(false);
+                // init button state and set as invisible
+                mButtonsPref.setButton3Text(R.string.wifi_connect)
+                        .setButton3Icon(R.drawable.ic_settings_wireless)
+                        .setButton3Enabled(true)
+                        .setButton3Visible(false);
                 break;
             case STATE_DISCONNECTED:
             case STATE_NOT_IN_RANGE:
index 906c55c..2bf3556 100644 (file)
@@ -35,6 +35,7 @@ import static org.mockito.Mockito.when;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Resources;
 import android.content.pm.PackageManager;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.ColorDrawable;
@@ -96,6 +97,7 @@ import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowToast;
 
 import java.net.Inet4Address;
 import java.net.InetAddress;
@@ -1310,6 +1312,406 @@ public class WifiDetailPreferenceControllerTest {
     }
 
     @Test
+    public void testConnectButton_shouldInvisibleForConnectNetwork() {
+        setUpForConnectedNetwork();
+
+        displayAndResume();
+
+        verify(mockButtonsPref, times(1)).setButton3Visible(false);
+    }
+
+    @Test
+    public void testConnectButton_shouldVisibleForDisconnectNetwork() {
+        setUpForDisconnectedNetwork();
+
+        displayAndResume();
+
+        verify(mockButtonsPref, times(1)).setButton3Visible(true);
+        verify(mockButtonsPref, times(1)).setButton3Text(R.string.wifi_connect);
+    }
+
+    private void setUpForToast() {
+        Resources res = mContext.getResources();
+        when(mockActivity.getResources()).thenReturn(res);
+    }
+
+    @Test
+    public void testConnectButton_clickConnect_displayAsSuccess() {
+        setUpForDisconnectedNetwork();
+        when(mockWifiManager.isWifiEnabled()).thenReturn(true);
+        InOrder inOrder = inOrder(mockButtonsPref);
+        String label = "title";
+        when(mockAccessPoint.getTitle()).thenReturn(label);
+        setUpForToast();
+
+        displayAndResume();
+
+        // check connect button exist
+        verifyConnectBtnSetUpAsVisible(inOrder);
+
+        // click connect button
+        mController.connectNetwork();
+
+        // check display button as connecting
+        verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
+        verifyConnectBtnSetUpAsConnecting(inOrder);
+
+        // update as connected
+        when(mockAccessPoint.isActive()).thenReturn(true);
+        mController.updateAccessPoint();
+
+        // check connect button invisible, be init as default state and toast success message
+        verifyConnectBtnBeInitAsDefault(inOrder);
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(false);
+        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+                mContext.getString(R.string.wifi_connected_to_message, label));
+    }
+
+    @Test
+    public void testConnectButton_clickConnectButFailed_displayFailMessage() {
+        setUpForDisconnectedNetwork();
+        ArgumentCaptor<WifiManager.ActionListener> connectListenerCaptor =
+                ArgumentCaptor.forClass(WifiManager.ActionListener.class);
+        when(mockWifiManager.isWifiEnabled()).thenReturn(true);
+        InOrder inOrder = inOrder(mockButtonsPref);
+        setUpForToast();
+
+        displayAndResume();
+
+        // check connect button exist
+        verifyConnectBtnSetUpAsVisible(inOrder);
+
+        // click connect button
+        mController.connectNetwork();
+
+        // check display button as connecting
+        verify(mockWifiManager, times(1)).connect(anyInt(), connectListenerCaptor.capture());
+        verifyConnectBtnSetUpAsConnecting(inOrder);
+
+        // update as failed
+        connectListenerCaptor.getValue().onFailure(-1);
+
+        // check connect button visible, be init as default and toast failed message
+        verifyConnectBtnBeInitAsDefault(inOrder);
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
+        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+                mContext.getString(R.string.wifi_failed_connect_message));
+    }
+
+    private void verifyConnectBtnSetUpAsVisible(InOrder inOrder) {
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Text(R.string.wifi_connect);
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Icon(R.drawable.ic_settings_wireless);
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
+    }
+
+    private void verifyConnectBtnSetUpAsConnecting(InOrder inOrder) {
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Text(R.string.wifi_connecting);
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Enabled(false);
+    }
+
+    private void verifyConnectBtnBeInitAsDefault(InOrder inOrder) {
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Text(R.string.wifi_connect);
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Icon(R.drawable.ic_settings_wireless);
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Enabled(true);
+    }
+
+    @Test
+    public void testConnectButton_clickConnectButTimeout_displayFailMessage() {
+        setUpForDisconnectedNetwork();
+        when(mockWifiManager.isWifiEnabled()).thenReturn(true);
+        InOrder inOrder = inOrder(mockButtonsPref);
+        setUpForToast();
+
+        displayAndResume();
+
+        // check connect button exist
+        verifyConnectBtnSetUpAsVisible(inOrder);
+
+        // click connect button
+        mController.connectNetwork();
+
+        // check display button as connecting
+        verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
+        verifyConnectBtnSetUpAsConnecting(inOrder);
+
+        // update as failed
+        mController.mTimer.onFinish();
+
+        // check connect button visible, be init as default and toast failed message
+        verifyConnectBtnBeInitAsDefault(inOrder);
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
+        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+                mContext.getString(R.string.wifi_failed_connect_message));
+    }
+
+    @Test
+    public void testConnectButton_clickConnectButTimeout_displayNotInRangeMessage() {
+        setUpForNotInRangeNetwork();
+        when(mockWifiManager.isWifiEnabled()).thenReturn(true);
+        InOrder inOrder = inOrder(mockButtonsPref);
+        setUpForToast();
+
+        displayAndResume();
+
+        // check connect button exist
+        verifyConnectBtnSetUpAsVisible(inOrder);
+
+        // click connect button
+        mController.connectNetwork();
+
+        // check display button as connecting
+        verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
+        verifyConnectBtnSetUpAsConnecting(inOrder);
+
+        // update as failed
+        mController.mTimer.onFinish();
+
+        // check connect button visible, be init as default and toast failed message
+        verifyConnectBtnBeInitAsDefault(inOrder);
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
+        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+                mContext.getString(R.string.wifi_not_in_range_message));
+    }
+
+    @Test
+    public void testConnectButton_clickConnectWhenWiFiDisabled_displaySuccessMessage() {
+        setUpForDisconnectedNetwork();
+        when(mockWifiManager.isWifiEnabled()).thenReturn(false); // wifi disabled
+        InOrder inOrder = inOrder(mockButtonsPref);
+        String label = "title";
+        when(mockAccessPoint.getTitle()).thenReturn(label);
+        setUpForToast();
+
+        displayAndResume();
+
+        // check connect button exist
+        verifyConnectBtnSetUpAsVisible(inOrder);
+
+        // click connect button
+        mController.connectNetwork();
+
+        // check turn on Wi-Fi, display button as connecting and toast turn on Wi-Fi message
+        verify(mockWifiManager, times(1)).setWifiEnabled(true);
+        verifyConnectBtnSetUpAsConnecting(inOrder);
+        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+                mContext.getString(R.string.wifi_turned_on_message));
+
+        // notify Wi-Fi enabled
+        mController.mWifiListener.onWifiStateChanged(WifiManager.WIFI_STATE_ENABLED);
+
+        // check had connect network and icon display as expected
+        verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
+        verifyConnectBtnSetUpAsConnecting(inOrder);
+
+        // update as connected
+        when(mockAccessPoint.isActive()).thenReturn(true);
+        mController.updateAccessPoint();
+
+        // check connect button invisible, be init as default state and toast success message
+        verifyConnectBtnBeInitAsDefault(inOrder);
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(false);
+        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+                mContext.getString(R.string.wifi_connected_to_message, label));
+    }
+
+    @Test
+    public void testConnectButton_clickConnectWhenWiFiDisabled_failedToConnectWiFi() {
+        setUpForDisconnectedNetwork();
+        when(mockWifiManager.isWifiEnabled()).thenReturn(false); // wifi disabled
+        InOrder inOrder = inOrder(mockButtonsPref);
+        setUpForToast();
+
+        displayAndResume();
+
+        // check connect button exist
+        verifyConnectBtnSetUpAsVisible(inOrder);
+
+        // click connect button
+        mController.connectNetwork();
+
+        // check turn on Wi-Fi, display button as connecting and toast turn on Wi-Fi message
+        verify(mockWifiManager, times(1)).setWifiEnabled(true);
+        verifyConnectBtnSetUpAsConnecting(inOrder);
+        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+                mContext.getString(R.string.wifi_turned_on_message));
+
+        // notify Wi-Fi enabled
+        mController.mWifiListener.onWifiStateChanged(WifiManager.WIFI_STATE_ENABLED);
+
+        // check had connect network and icon display as expected
+        verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
+        verifyConnectBtnSetUpAsConnecting(inOrder);
+
+        // update as failed
+        mController.mTimer.onFinish();
+
+        // check connect button visible, be init as default and toast failed message
+        verifyConnectBtnBeInitAsDefault(inOrder);
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
+        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+                mContext.getString(R.string.wifi_failed_connect_message));
+    }
+
+    @Test
+    public void
+            testConnectButton_clickConnectWhenWiFiDisabled_failedToConnectWifiBecauseNotInRange() {
+        setUpForNotInRangeNetwork();
+        when(mockWifiManager.isWifiEnabled()).thenReturn(false); // wifi disabled
+        InOrder inOrder = inOrder(mockButtonsPref);
+        setUpForToast();
+
+        displayAndResume();
+
+        // check connect button exist
+        verifyConnectBtnSetUpAsVisible(inOrder);
+
+        // click connect button
+        mController.connectNetwork();
+
+        // check turn on Wi-Fi, display button as connecting and toast turn on Wi-Fi message
+        verify(mockWifiManager, times(1)).setWifiEnabled(true);
+        verifyConnectBtnSetUpAsConnecting(inOrder);
+        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+                mContext.getString(R.string.wifi_turned_on_message));
+
+        // notify Wi-Fi enabled
+        mController.mWifiListener.onWifiStateChanged(WifiManager.WIFI_STATE_ENABLED);
+
+        // check had connect network and icon display as expected
+        verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
+        verifyConnectBtnSetUpAsConnecting(inOrder);
+
+        // update as failed
+        mController.mTimer.onFinish();
+
+        // check connect button visible, be init as default and toast failed message
+        verifyConnectBtnBeInitAsDefault(inOrder);
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
+        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+                mContext.getString(R.string.wifi_not_in_range_message));
+    }
+
+    @Test
+    public void testConnectButton_clickConnectWhenWiFiDisabled_failedToEnableWifi() {
+        setUpForDisconnectedNetwork();
+        when(mockWifiManager.isWifiEnabled()).thenReturn(false); // wifi disabled
+        InOrder inOrder = inOrder(mockButtonsPref);
+        setUpForToast();
+
+        displayAndResume();
+
+        // check connect button exist
+        verifyConnectBtnSetUpAsVisible(inOrder);
+
+        // click connect button
+        mController.connectNetwork();
+
+        // check turn on Wi-Fi, display button as connecting and toast turn on Wi-Fi message
+        verify(mockWifiManager, times(1)).setWifiEnabled(true);
+        verifyConnectBtnSetUpAsConnecting(inOrder);
+        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+                mContext.getString(R.string.wifi_turned_on_message));
+
+        // notify turn on Wi-Fi failed
+        mController.mTimer.onFinish();
+
+        // check connect button visible, be init as default and toast failed message
+        verifyConnectBtnBeInitAsDefault(inOrder);
+        inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
+        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+                mContext.getString(R.string.wifi_failed_connect_message));
+    }
+
+    @Test
+    public void updateAccessPoint_returnFalseForNothingChanged() {
+        setUpForDisconnectedNetwork();
+
+        displayAndResume();
+        boolean changed = mController.updateAccessPoint();
+
+        assertThat(changed).isFalse();
+    }
+
+    @Test
+    public void updateAccessPoint_returnTrueForSignalLevelChanged() {
+        setUpForDisconnectedNetwork();
+
+        displayAndResume();
+
+        // Level changed
+        when(mockAccessPoint.getLevel()).thenReturn(LEVEL + 1);
+        boolean changed = mController.updateAccessPoint();
+
+        assertThat(changed).isTrue();
+    }
+
+    @Test
+    public void updateAccessPoint_returnTrueForChangeAsNotInRange() {
+        setUpForDisconnectedNetwork();
+
+        displayAndResume();
+
+        // change as not in range
+        when(mockAccessPoint.matches(any(WifiConfiguration.class))).thenReturn(false);
+        boolean changed = mController.updateAccessPoint();
+
+        assertThat(changed).isTrue();
+    }
+
+    @Test
+    public void updateAccessPoint_returnTrueForChangeAsInRange() {
+        setUpForNotInRangeNetwork();
+
+        displayAndResume();
+
+        // change as in range
+        when(mockAccessPoint.matches(any(WifiConfiguration.class))).thenReturn(true);
+        boolean changed = mController.updateAccessPoint();
+
+        assertThat(changed).isTrue();
+    }
+
+    @Test
+    public void updateAccessPoint_returnTrueForChangeAsConnected() {
+        setUpForDisconnectedNetwork();
+
+        displayAndResume();
+
+        // change as connected
+        when(mockAccessPoint.isActive()).thenReturn(true);
+        boolean changed = mController.updateAccessPoint();
+
+        assertThat(changed).isTrue();
+    }
+
+    @Test
+    public void updateAccessPoint_returnTrueForChangeAsDisconnected() {
+        setUpForConnectedNetwork();
+
+        displayAndResume();
+
+        // change as disconnected
+        when(mockAccessPoint.isActive()).thenReturn(false);
+        boolean changed = mController.updateAccessPoint();
+
+        assertThat(changed).isTrue();
+    }
+
+    @Test
+    public void updateAccessPoint_returnTrueForAccessPointUpdated() {
+        setUpForConnectedNetwork();
+
+        displayAndResume();
+
+        // change as disconnected
+        when(mockAccessPoint.update(mockWifiConfig, mockWifiInfo, mockNetworkInfo))
+                .thenReturn(true);
+        boolean changed = mController.updateAccessPoint();
+
+        assertThat(changed).isTrue();
+    }
+
+    @Test
     public void testRefreshRssiViews_shouldNotUpdateIfLevelIsSameForConnectedNetwork() {
         setUpForConnectedNetwork();
         displayAndResume();