Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f303d5f authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Show "Forget" button for ephemeral networks." into oc-dev

parents 816956d2 dec19d10
Loading
Loading
Loading
Loading
+34 −22
Original line number Diff line number Diff line
@@ -15,6 +15,9 @@
 */
package com.android.settings.wifi.details;

import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;

import android.app.Fragment;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -28,8 +31,8 @@ import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkBadging;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.NetworkUtils;
import android.net.RouteInfo;
import android.net.wifi.WifiConfiguration;
@@ -41,19 +44,21 @@ import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Button;
import android.view.View;
import android.widget.Button;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.PreferenceController;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.core.lifecycle.Lifecycle;
import com.android.settings.core.lifecycle.LifecycleObserver;
import com.android.settings.core.lifecycle.events.OnPause;
import com.android.settings.core.lifecycle.events.OnResume;
import com.android.settings.wifi.WifiDetailPreference;
import com.android.settings.vpn2.ConnectivityManagerWrapper;
import com.android.settings.wifi.WifiDetailPreference;
import com.android.settingslib.wifi.AccessPoint;

import java.net.Inet4Address;
@@ -63,9 +68,6 @@ import java.net.UnknownHostException;
import java.util.List;
import java.util.StringJoiner;

import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;

/**
 * Controller for logic pertaining to displaying Wifi information for the
 * {@link WifiNetworkDetailsFragment}.
@@ -115,10 +117,12 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
    private final WifiConfiguration mWifiConfig;
    private WifiInfo mWifiInfo;
    private final WifiManager mWifiManager;
    private final MetricsFeatureProvider mMetricsFeatureProvider;

    // UI elements - in order of appearance
    private Preference mConnectionDetailPref;
    private LayoutPreference mButtonsPref;
    private Button mForgetButton;
    private Button mSignInButton;
    private WifiDetailPreference mSignalStrengthPref;
    private WifiDetailPreference mLinkSpeedPref;
@@ -129,8 +133,8 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
    private WifiDetailPreference mGatewayPref;
    private WifiDetailPreference mSubnetPref;
    private WifiDetailPreference mDnsPref;
    private PreferenceCategory mIpv6AddressCategory;

    private PreferenceCategory mIpv6AddressCategory;
    private final IntentFilter mFilter;
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
@@ -179,7 +183,8 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
            Fragment fragment,
            Handler handler,
            Lifecycle lifecycle,
            WifiManager wifiManager) {
            WifiManager wifiManager,
            MetricsFeatureProvider metricsFeatureProvider) {
        super(context);

        mAccessPoint = accessPoint;
@@ -187,11 +192,10 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
        mConnectivityManagerWrapper = connectivityManagerWrapper;
        mFragment = fragment;
        mHandler = handler;
        mNetworkInfo = accessPoint.getNetworkInfo();
        mRssi = accessPoint.getRssi();
        mSignalStr = context.getResources().getStringArray(R.array.wifi_signal);
        mWifiConfig = accessPoint.getConfig();
        mWifiManager = wifiManager;
        mMetricsFeatureProvider = metricsFeatureProvider;

        mFilter = new IntentFilter();
        mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
@@ -241,22 +245,18 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
                (PreferenceCategory) screen.findPreference(KEY_IPV6_ADDRESS_CATEGORY);

        mSecurityPref.setDetailText(mAccessPoint.getSecurityString(false /* concise */));
    }

    public WifiInfo getWifiInfo() {
        return mWifiInfo;
        mForgetButton = (Button) mButtonsPref.findViewById(R.id.left_button);
        mForgetButton.setText(R.string.forget);
        mForgetButton.setOnClickListener(view -> forgetNetwork());
        updateInfo();
    }

    @Override
    public void onResume() {
        mConnectivityManagerWrapper.registerNetworkCallback(mNetworkRequest, mNetworkCallback,
                mHandler);
        mNetwork = mWifiManager.getCurrentNetwork();
        mLinkProperties = mConnectivityManager.getLinkProperties(mNetwork);
        mNetworkCapabilities = mConnectivityManager.getNetworkCapabilities(mNetwork);

        updateInfo();

        // updateInfo() will be called during registration because NETWORK_STATE_CHANGED_ACTION is
        // a sticky broadcast.
        mContext.registerReceiver(mReceiver, mFilter);
    }

@@ -265,11 +265,16 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
        mNetwork = null;
        mLinkProperties = null;
        mNetworkCapabilities = null;
        mNetworkInfo = null;
        mWifiInfo = null;
        mContext.unregisterReceiver(mReceiver);
        mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
    }

    private void updateInfo() {
        mNetwork = mWifiManager.getCurrentNetwork();
        mLinkProperties = mConnectivityManager.getLinkProperties(mNetwork);
        mNetworkCapabilities = mConnectivityManager.getNetworkCapabilities(mNetwork);
        mNetworkInfo = mConnectivityManager.getNetworkInfo(mNetwork);
        mWifiInfo = mWifiManager.getConnectionInfo();
        if (mNetwork == null || mNetworkInfo == null || mWifiInfo == null) {
@@ -277,6 +282,9 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
            return;
        }

        // Update whether the forgot button should be displayed.
        mForgetButton.setVisibility(canForgetNetwork() ? View.VISIBLE : View.INVISIBLE);

        refreshNetworkState();

        // Update Connection Header icon and Signal Strength Preference
@@ -307,6 +315,8 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
        mFrequencyPref.setDetailText(band);

        updateIpLayerInfo();
        mButtonsPref.setVisible(mForgetButton.getVisibility() == View.VISIBLE
                || mSignInButton.getVisibility() == View.VISIBLE);
    }

    private void exitActivity() {
@@ -422,7 +432,7 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
    /**
     * Returns whether the network represented by this preference can be forgotten.
     */
    public boolean canForgetNetwork() {
    private boolean canForgetNetwork() {
        return mWifiInfo != null && mWifiInfo.isEphemeral() || mWifiConfig != null;
    }

@@ -437,7 +447,7 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
    /**
     * Forgets the wifi network associated with this preference.
     */
    public void forgetNetwork() {
    private void forgetNetwork() {
        if (mWifiInfo != null && mWifiInfo.isEphemeral()) {
            mWifiManager.disableEphemeralNetwork(mWifiInfo.getSSID());
        } else if (mWifiConfig != null) {
@@ -447,6 +457,8 @@ public class WifiDetailPreferenceController extends PreferenceController impleme
                mWifiManager.forget(mWifiConfig.networkId, null /* action listener */);
            }
        }
        mMetricsFeatureProvider.action(
                mFragment.getActivity(), MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
        mFragment.getActivity().finish();
    }
}
+2 −26
Original line number Diff line number Diff line
@@ -17,17 +17,13 @@ package com.android.settings.wifi.details;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.NetworkRequest;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.widget.Button;

import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.PreferenceController;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.vpn2.ConnectivityManagerWrapperImpl;
@@ -46,7 +42,6 @@ public class WifiNetworkDetailsFragment extends DashboardFragment {
    private static final String TAG = "WifiNetworkDetailsFrg";

    private AccessPoint mAccessPoint;
    private Button mForgetButton;
    private WifiDetailPreferenceController mWifiDetailPreferenceController;

    @Override
@@ -55,26 +50,6 @@ public class WifiNetworkDetailsFragment extends DashboardFragment {
        super.onAttach(context);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Header Title set automatically from launching Preference

        LayoutPreference buttonsPreference = ((LayoutPreference) findPreference(
                WifiDetailPreferenceController.KEY_BUTTONS_PREF));
        buttonsPreference.setVisible(mWifiDetailPreferenceController.canForgetNetwork());

        mForgetButton = (Button) buttonsPreference.findViewById(R.id.left_button);
        mForgetButton.setText(R.string.forget);
        mForgetButton.setOnClickListener(view -> forgetNetwork());
    }

    private void forgetNetwork() {
        mMetricsFeatureProvider.action(getActivity(), MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
        mWifiDetailPreferenceController.forgetNetwork();
    }

    @Override
    public int getMetricsCategory() {
        return MetricsProto.MetricsEvent.WIFI_NETWORK_DETAILS;
@@ -100,7 +75,8 @@ public class WifiNetworkDetailsFragment extends DashboardFragment {
                this,
                new Handler(Looper.getMainLooper()),  // UI thread.
                getLifecycle(),
                context.getSystemService(WifiManager.class));
                context.getSystemService(WifiManager.class),
                mMetricsFeatureProvider);

        ArrayList<PreferenceController> controllers = new ArrayList(1);
        controllers.add(mWifiDetailPreferenceController);
+91 −42
Original line number Diff line number Diff line
@@ -52,14 +52,15 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.core.lifecycle.Lifecycle;
import com.android.settings.wifi.WifiDetailPreference;
import com.android.settings.vpn2.ConnectivityManagerWrapper;
import com.android.settings.vpn2.ConnectivityManagerWrapperImpl;
import com.android.settings.wifi.WifiDetailPreference;
import com.android.settingslib.wifi.AccessPoint;

import org.junit.Before;
@@ -67,6 +68,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -103,6 +105,7 @@ public class WifiDetailPreferenceControllerTest {
    @Mock private WifiInfo mockWifiInfo;
    @Mock private WifiNetworkDetailsFragment mockFragment;
    @Mock private WifiManager mockWifiManager;
    @Mock private MetricsFeatureProvider mockMetricsFeatureProvider;

    @Mock private Preference mockConnectionDetailPref;
    @Mock private LayoutPreference mockButtonsPref;
@@ -116,9 +119,12 @@ public class WifiDetailPreferenceControllerTest {
    @Mock private WifiDetailPreference mockGatewayPref;
    @Mock private WifiDetailPreference mockSubnetPref;
    @Mock private WifiDetailPreference mockDnsPref;
    @Mock private Button mockForgetButton;
    @Mock private PreferenceCategory mockIpv6AddressCategory;

    private ArgumentCaptor<NetworkCallback> mCallbackCaptor;
    @Captor private ArgumentCaptor<NetworkCallback> mCallbackCaptor;
    @Captor private ArgumentCaptor<View.OnClickListener> mForgetClickListener;

    private Context mContext = RuntimeEnvironment.application;
    private Lifecycle mLifecycle;
    private LinkProperties mLinkProperties;
@@ -143,12 +149,8 @@ public class WifiDetailPreferenceControllerTest {
            throw new RuntimeException(e);
        }

        mCallbackCaptor = ArgumentCaptor.forClass(NetworkCallback.class);

        when(mockAccessPoint.getConfig()).thenReturn(mockWifiConfig);
        when(mockAccessPoint.getLevel()).thenReturn(LEVEL);
        when(mockAccessPoint.getNetworkInfo()).thenReturn(mockNetworkInfo);
        when(mockAccessPoint.getRssi()).thenReturn(RSSI);
        when(mockAccessPoint.getSecurityString(false)).thenReturn(SECURITY);

        when(mockConnectivityManagerWrapper.getConnectivityManager())
@@ -157,6 +159,7 @@ public class WifiDetailPreferenceControllerTest {
                .thenReturn(mockNetworkInfo);
        doNothing().when(mockConnectivityManagerWrapper).registerNetworkCallback(
                any(NetworkRequest.class), mCallbackCaptor.capture(), any(Handler.class));
        doNothing().when(mockForgetButton).setOnClickListener(mForgetClickListener.capture());

        when(mockWifiInfo.getLinkSpeed()).thenReturn(LINK_SPEED);
        when(mockWifiInfo.getRssi()).thenReturn(RSSI);
@@ -169,9 +172,8 @@ public class WifiDetailPreferenceControllerTest {

        when(mockFragment.getActivity()).thenReturn(mockActivity);

        mController = newWifiDetailPreferenceController();

        setupMockedPreferenceScreen();
        mController = newWifiDetailPreferenceController();
    }

    private WifiDetailPreferenceController newWifiDetailPreferenceController() {
@@ -182,7 +184,8 @@ public class WifiDetailPreferenceControllerTest {
                mockFragment,
                null,  // Handler
                mLifecycle,
                mockWifiManager);
                mockWifiManager,
                mockMetricsFeatureProvider);
    }

    private void setupMockedPreferenceScreen() {
@@ -192,6 +195,8 @@ public class WifiDetailPreferenceControllerTest {
                .thenReturn(mockConnectionDetailPref);
        when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_BUTTONS_PREF))
                .thenReturn(mockButtonsPref);
        when(mockButtonsPref.findViewById(R.id.left_button))
                .thenReturn(mockForgetButton);
        when(mockButtonsPref.findViewById(R.id.right_button))
                .thenReturn(mockSignInButton);
        when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SIGNAL_STRENGTH_PREF))
@@ -214,30 +219,32 @@ public class WifiDetailPreferenceControllerTest {
                .thenReturn(mockDnsPref);
        when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_IPV6_ADDRESS_CATEGORY))
                .thenReturn(mockIpv6AddressCategory);

        mController.displayPreference(mockScreen);
    }

    @Test
    public void isAvailable_shouldAlwaysReturnTrue() {
        mController.displayPreference(mockScreen);

        assertThat(mController.isAvailable()).isTrue();
    }

    @Test
    public void securityPreference_stringShouldBeSet() {
        mController.displayPreference(mockScreen);

        verify(mockSecurityPref).setDetailText(SECURITY);
    }

    @Test
    public void latestWifiInfo_shouldBeFetchedOnResume() {
        mController.onResume();
    public void latestWifiInfo_shouldBeFetchedInDisplayPreference() {
        mController.displayPreference(mockScreen);

        verify(mockWifiManager, times(1)).getConnectionInfo();
    }

    @Test
    public void latestNetworkInfo_shouldBeFetchedOnResume() {
        mController.onResume();
    public void latestNetworkInfo_shouldBeFetchedInDisplayPreference() {
        mController.displayPreference(mockScreen);

        verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
    }
@@ -264,7 +271,7 @@ public class WifiDetailPreferenceControllerTest {
        Drawable expectedIcon =
                NetworkBadging.getWifiIcon(LEVEL, NetworkBadging.BADGING_NONE, mContext.getTheme());

        mController.onResume();
        mController.displayPreference(mockScreen);

        verify(mockConnectionDetailPref).setIcon(expectedIcon);
    }
@@ -274,14 +281,14 @@ public class WifiDetailPreferenceControllerTest {
        String summary = "summary";
        when(mockAccessPoint.getSettingsSummary()).thenReturn(summary);

        mController.onResume();
        mController.displayPreference(mockScreen);

        verify(mockConnectionDetailPref).setTitle(summary);
    }

    @Test
    public void signalStrengthPref_shouldHaveIconSet() {
        mController.onResume();
        mController.displayPreference(mockScreen);

        verify(mockSignalStrengthPref).setIcon(any(Drawable.class));
    }
@@ -291,7 +298,7 @@ public class WifiDetailPreferenceControllerTest {
        String expectedStrength =
                mContext.getResources().getStringArray(R.array.wifi_signal)[LEVEL];

        mController.onResume();
        mController.displayPreference(mockScreen);

        verify(mockSignalStrengthPref).setDetailText(expectedStrength);
    }
@@ -300,7 +307,7 @@ public class WifiDetailPreferenceControllerTest {
    public void linkSpeedPref_shouldHaveDetailTextSet() {
        String expectedLinkSpeed = mContext.getString(R.string.link_speed, LINK_SPEED);

        mController.onResume();
        mController.displayPreference(mockScreen);

        verify(mockLinkSpeedPref).setDetailText(expectedLinkSpeed);
    }
@@ -309,14 +316,14 @@ public class WifiDetailPreferenceControllerTest {
    public void linkSpeedPref_shouldNotShowIfNotSet() {
        when(mockWifiInfo.getLinkSpeed()).thenReturn(-1);

        mController.onResume();
        mController.displayPreference(mockScreen);

        verify(mockLinkSpeedPref).setVisible(false);
    }

    @Test
    public void macAddressPref_shouldHaveDetailTextSet() {
        mController.onResume();
        mController.displayPreference(mockScreen);

        verify(mockMacAddressPref).setDetailText(MAC_ADDRESS);
    }
@@ -327,7 +334,7 @@ public class WifiDetailPreferenceControllerTest {

        mLinkProperties.addLinkAddress(ipv4Address);

        mController.onResume();
        mController.displayPreference(mockScreen);

        verify(mockIpAddressPref).setDetailText(mIpv4Address.getHostAddress());
    }
@@ -339,7 +346,7 @@ public class WifiDetailPreferenceControllerTest {
        InetAddress gateway = mIpv4Address;
        mLinkProperties.addRoute(new RouteInfo(subnet, gateway));

        mController.onResume();
        mController.displayPreference(mockScreen);

        verify(mockSubnetPref).setDetailText("255.255.255.0");
        verify(mockGatewayPref).setDetailText(mIpv4Address.getHostAddress());
@@ -350,7 +357,7 @@ public class WifiDetailPreferenceControllerTest {
        mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[]{8,8,4,4}));
        mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[]{8,8,8,8}));

        mController.onResume();
        mController.displayPreference(mockScreen);

        verify(mockDnsPref).setDetailText("8.8.4.4,8.8.8.8");
    }
@@ -361,7 +368,7 @@ public class WifiDetailPreferenceControllerTest {
        // nor connecting and WifiStateMachine has not reached L2ConnectedState.
        when(mockWifiManager.getCurrentNetwork()).thenReturn(null);

        mController.onResume();
        mController.displayPreference(mockScreen);

        verify(mockActivity).finish();
    }
@@ -372,7 +379,7 @@ public class WifiDetailPreferenceControllerTest {
        reset(mockIpv6AddressCategory, mockIpAddressPref, mockSubnetPref, mockGatewayPref,
                mockDnsPref);

        mController.onResume();
        mController.displayPreference(mockScreen);

        verify(mockIpv6AddressCategory).setVisible(false);
        verify(mockIpAddressPref).setVisible(false);
@@ -389,27 +396,28 @@ public class WifiDetailPreferenceControllerTest {
    @Test
    public void canForgetNetwork_noNetwork() {
        when(mockAccessPoint.getConfig()).thenReturn(null);

        mController = newWifiDetailPreferenceController();
        mController.displayPreference(mockScreen);
        mController.onResume();

        assertThat(mController.canForgetNetwork()).isFalse();
        verify(mockForgetButton).setVisibility(View.INVISIBLE);
    }

    @Test
    public void canForgetNetwork_ephemeral() {
        when(mockWifiInfo.isEphemeral()).thenReturn(true);
        when(mockAccessPoint.getConfig()).thenReturn(null);
        mController = newWifiDetailPreferenceController();

        mController.displayPreference(mockScreen);
        mController.onResume();

        assertThat(mController.canForgetNetwork()).isTrue();
        verify(mockForgetButton).setVisibility(View.VISIBLE);
    }

    @Test
    public void canForgetNetwork_saved() {
        assertThat(mController.canForgetNetwork()).isTrue();
        mController.displayPreference(mockScreen);

        verify(mockForgetButton).setVisibility(View.VISIBLE);
    }

    @Test
@@ -418,25 +426,31 @@ public class WifiDetailPreferenceControllerTest {
        when(mockWifiInfo.isEphemeral()).thenReturn(true);
        when(mockWifiInfo.getSSID()).thenReturn(ssid);

        mController.onResume();

        mController.forgetNetwork();
        mController.displayPreference(mockScreen);
        mForgetClickListener.getValue().onClick(null);

        verify(mockWifiManager).disableEphemeralNetwork(ssid);
        verify(mockMetricsFeatureProvider)
                .action(mockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
    }

    @Test
    public void forgetNetwork_saved() {
        mockWifiConfig.networkId = 5;

        mController.forgetNetwork();
        mController.displayPreference(mockScreen);
        mForgetClickListener.getValue().onClick(null);

        verify(mockWifiManager).forget(mockWifiConfig.networkId, null);
        verify(mockMetricsFeatureProvider)
                .action(mockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
    }

    @Test
    public void networkStateChangedIntent_shouldRefetchInfo() {
        mController.displayPreference(mockScreen);
        mController.onResume();

        verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
        verify(mockWifiManager, times(1)).getConnectionInfo();

@@ -448,7 +462,9 @@ public class WifiDetailPreferenceControllerTest {

    @Test
    public void rssiChangedIntent_shouldRefetchInfo() {
        mController.displayPreference(mockScreen);
        mController.onResume();

        verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class));
        verify(mockWifiManager, times(1)).getConnectionInfo();

@@ -470,6 +486,7 @@ public class WifiDetailPreferenceControllerTest {

    @Test
    public void networkOnLost_shouldFinishActivity() {
        mController.displayPreference(mockScreen);
        mController.onResume();

        mCallbackCaptor.getValue().onLost(mockNetwork);
@@ -483,7 +500,7 @@ public class WifiDetailPreferenceControllerTest {

        mLinkProperties.addLinkAddress(ipv6Address);

        mController.onResume();
        mController.displayPreference(mockScreen);

        ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass(Preference.class);
        verify(mockIpv6AddressCategory).addPreference(preferenceCaptor.capture());
@@ -496,7 +513,7 @@ public class WifiDetailPreferenceControllerTest {

        mLinkProperties.addLinkAddress(ipv6Address);

        mController.onResume();
        mController.displayPreference(mockScreen);

        ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass(Preference.class);
        verify(mockIpv6AddressCategory).addPreference(preferenceCaptor.capture());
@@ -505,9 +522,11 @@ public class WifiDetailPreferenceControllerTest {

    @Test
    public void captivePortal_shouldShowSignInButton() {
        reset(mockSignInButton);
        InOrder inOrder = inOrder(mockSignInButton);

        mController.displayPreference(mockScreen);
        mController.onResume();

        inOrder.verify(mockSignInButton).setVisibility(View.INVISIBLE);

        NetworkCapabilities nc = new NetworkCapabilities();
@@ -531,11 +550,41 @@ public class WifiDetailPreferenceControllerTest {

    @Test
    public void testSignInButton_shouldStartCaptivePortalApp() {
        mController.onResume();
        mController.displayPreference(mockScreen);

        ArgumentCaptor<OnClickListener> captor = ArgumentCaptor.forClass(OnClickListener.class);
        verify(mockSignInButton).setOnClickListener(captor.capture());
        captor.getValue().onClick(mockSignInButton);
        verify(mockConnectivityManagerWrapper).startCaptivePortalApp(mockNetwork);
    }

    @Test
    public void signInButtonVisible_buttonPanelShouldBeVisible() {
        when(mockSignInButton.getVisibility()).thenReturn(View.VISIBLE);
        when(mockForgetButton.getVisibility()).thenReturn(View.INVISIBLE);

        mController.displayPreference(mockScreen);

        verify(mockButtonsPref).setVisible(true);
    }

    @Test
    public void forgetButtonVisible_buttonPanelShouldBeVisible() {
        when(mockSignInButton.getVisibility()).thenReturn(View.INVISIBLE);
        when(mockForgetButton.getVisibility()).thenReturn(View.VISIBLE);

        mController.displayPreference(mockScreen);

        verify(mockButtonsPref).setVisible(true);
    }

    @Test
    public void neitherButtonVisible_buttonPanelShouldBeInvisible() {
        when(mockSignInButton.getVisibility()).thenReturn(View.INVISIBLE);
        when(mockForgetButton.getVisibility()).thenReturn(View.INVISIBLE);

        mController.displayPreference(mockScreen);

        verify(mockButtonsPref).setVisible(false);
    }
}