Merge "Auto-open Captive Portal when user clicks on open network."

This commit is contained in:
Thomas Devaux
2020-02-12 02:37:58 +00:00
committed by Android (Google) Code Review
3 changed files with 220 additions and 31 deletions

View File

@@ -22,7 +22,7 @@ import android.net.NetworkCapabilities;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
/** Listens for changes to NetworkCapabilities to update the ConnectedAccessPointPreference. */ /** Listens for changes to NetworkCapabilities to update the ConnectedAccessPointPreference. */
final class CaptivePortalNetworkCallback extends NetworkCallback { class CaptivePortalNetworkCallback extends NetworkCallback {
private final ConnectedAccessPointPreference mConnectedApPreference; private final ConnectedAccessPointPreference mConnectedApPreference;
private final Network mNetwork; private final Network mNetwork;
@@ -36,25 +36,42 @@ final class CaptivePortalNetworkCallback extends NetworkCallback {
} }
@Override @Override
public void onLost(Network network) { public final void onLost(Network network) {
if (mNetwork.equals(network)) { if (mNetwork.equals(network)) {
mIsCaptivePortal = false; setIsCaptivePortal(false);
} }
} }
@Override @Override
public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { public final void onCapabilitiesChanged(Network network,
NetworkCapabilities networkCapabilities) {
if (mNetwork.equals(network)) { if (mNetwork.equals(network)) {
mIsCaptivePortal = WifiUtils.canSignIntoNetwork(networkCapabilities); boolean isCaptivePortal = WifiUtils.canSignIntoNetwork(networkCapabilities);
mConnectedApPreference.setCaptivePortal(mIsCaptivePortal); setIsCaptivePortal(isCaptivePortal);
mConnectedApPreference.setCaptivePortal(isCaptivePortal);
} }
} }
/**
* Called when captive portal capability changes for the current network. Default implementation
* is a no-op. Use {@link CaptivePortalNetworkCallback#isCaptivePortal()} to read new
* capability.
*/
public void onCaptivePortalCapabilityChanged() {}
private void setIsCaptivePortal(boolean isCaptivePortal) {
if (isCaptivePortal == mIsCaptivePortal) {
return;
}
mIsCaptivePortal = isCaptivePortal;
onCaptivePortalCapabilityChanged();
}
/** /**
* Returns true if the supplied network and preference are not null and are the same as the * Returns true if the supplied network and preference are not null and are the same as the
* originally supplied values. * originally supplied values.
*/ */
public boolean isSameNetworkAndPreference( public final boolean isSameNetworkAndPreference(
Network network, ConnectedAccessPointPreference connectedApPreference) { Network network, ConnectedAccessPointPreference connectedApPreference) {
return mNetwork.equals(network) && mConnectedApPreference == connectedApPreference; return mNetwork.equals(network) && mConnectedApPreference == connectedApPreference;
} }
@@ -63,12 +80,12 @@ final class CaptivePortalNetworkCallback extends NetworkCallback {
* Returns true if the most recent update to the NetworkCapabilities indicates a captive portal * Returns true if the most recent update to the NetworkCapabilities indicates a captive portal
* network and the Network was not lost in the interim. * network and the Network was not lost in the interim.
*/ */
public boolean isCaptivePortal() { public final boolean isCaptivePortal() {
return mIsCaptivePortal; return mIsCaptivePortal;
} }
/** Returns the currently associated network. */ /** Returns the currently associated network. */
public Network getNetwork() { public final Network getNetwork() {
return mNetwork; return mNetwork;
} }
} }

View File

@@ -50,6 +50,7 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.IntDef;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceCategory;
@@ -135,12 +136,16 @@ public class WifiSettings extends RestrictedSettingsFragment
setProgressBarVisible(false); setProgressBarVisible(false);
}; };
protected WifiManager mWifiManager; @VisibleForTesting
private ConnectivityManager mConnectivityManager; WifiManager mWifiManager;
@VisibleForTesting
ConnectivityManager mConnectivityManager;
private WifiManager.ActionListener mConnectListener; private WifiManager.ActionListener mConnectListener;
private WifiManager.ActionListener mSaveListener; private WifiManager.ActionListener mSaveListener;
private WifiManager.ActionListener mForgetListener; private WifiManager.ActionListener mForgetListener;
private CaptivePortalNetworkCallback mCaptivePortalNetworkCallback; @VisibleForTesting
CaptivePortalNetworkCallback mCaptivePortalNetworkCallback;
private Network mLastNetworkCaptivePortalAppStarted;
/** /**
* The state of {@link #isUiRestricted()} at {@link #onCreate(Bundle)}}. This is neccesary to * The state of {@link #isUiRestricted()} at {@link #onCreate(Bundle)}}. This is neccesary to
@@ -196,6 +201,15 @@ public class WifiSettings extends RestrictedSettingsFragment
* network once connected. * network once connected.
*/ */
private boolean mClickedConnect; private boolean mClickedConnect;
@ConnectSource int mConnectSource = CONNECT_SOURCE_UNSPECIFIED;
private static final int CONNECT_SOURCE_UNSPECIFIED = 0;
private static final int CONNECT_SOURCE_NETWORK_MENU_ITEM_CLICK = 1;
private static final int CONNECT_SOURCE_NETWORK_LIST_ITEM_CLICK = 2;
@IntDef({CONNECT_SOURCE_UNSPECIFIED, CONNECT_SOURCE_NETWORK_MENU_ITEM_CLICK,
CONNECT_SOURCE_NETWORK_LIST_ITEM_CLICK})
private @interface ConnectSource {}
/* End of "used in Wifi Setup context" */ /* End of "used in Wifi Setup context" */
@@ -512,12 +526,14 @@ public class WifiSettings extends RestrictedSettingsFragment
case MENU_ID_CONNECT: { case MENU_ID_CONNECT: {
boolean isSavedNetwork = mSelectedAccessPoint.isSaved(); boolean isSavedNetwork = mSelectedAccessPoint.isSaved();
if (isSavedNetwork) { if (isSavedNetwork) {
connect(mSelectedAccessPoint.getConfig(), isSavedNetwork); connect(mSelectedAccessPoint.getConfig(), isSavedNetwork,
CONNECT_SOURCE_NETWORK_MENU_ITEM_CLICK);
} else if ((mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) || } else if ((mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) ||
(mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_OWE)) { (mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_OWE)) {
/** Bypass dialog for unsecured networks */ /** Bypass dialog for unsecured networks */
mSelectedAccessPoint.generateOpenNetworkConfig(); mSelectedAccessPoint.generateOpenNetworkConfig();
connect(mSelectedAccessPoint.getConfig(), isSavedNetwork); connect(mSelectedAccessPoint.getConfig(), isSavedNetwork,
CONNECT_SOURCE_NETWORK_MENU_ITEM_CLICK);
} else { } else {
showDialog(mSelectedAccessPoint, WifiConfigUiBase.MODE_CONNECT); showDialog(mSelectedAccessPoint, WifiConfigUiBase.MODE_CONNECT);
} }
@@ -563,11 +579,15 @@ public class WifiSettings extends RestrictedSettingsFragment
case WifiUtils.CONNECT_TYPE_OPEN_NETWORK: case WifiUtils.CONNECT_TYPE_OPEN_NETWORK:
mSelectedAccessPoint.generateOpenNetworkConfig(); mSelectedAccessPoint.generateOpenNetworkConfig();
connect(mSelectedAccessPoint.getConfig(), mSelectedAccessPoint.isSaved()); connect(mSelectedAccessPoint.getConfig(),
mSelectedAccessPoint.isSaved(),
CONNECT_SOURCE_NETWORK_LIST_ITEM_CLICK);
break; break;
case WifiUtils.CONNECT_TYPE_SAVED_NETWORK: case WifiUtils.CONNECT_TYPE_SAVED_NETWORK:
connect(mSelectedAccessPoint.getConfig(), true /* isSavedNetwork */); connect(mSelectedAccessPoint.getConfig(),
true /* isSavedNetwork */,
CONNECT_SOURCE_NETWORK_LIST_ITEM_CLICK);
break; break;
default: default:
@@ -705,6 +725,8 @@ public class WifiSettings extends RestrictedSettingsFragment
setOffMessage(); setOffMessage();
setAdditionalSettingsSummaries(); setAdditionalSettingsSummaries();
setProgressBarVisible(false); setProgressBarVisible(false);
mConnectSource = CONNECT_SOURCE_UNSPECIFIED;
mClickedConnect = false;
break; break;
} }
} }
@@ -876,7 +898,7 @@ public class WifiSettings extends RestrictedSettingsFragment
pref.getAccessPoint().saveWifiState(pref.getExtras()); pref.getAccessPoint().saveWifiState(pref.getExtras());
if (mCaptivePortalNetworkCallback != null if (mCaptivePortalNetworkCallback != null
&& mCaptivePortalNetworkCallback.isCaptivePortal()) { && mCaptivePortalNetworkCallback.isCaptivePortal()) {
mConnectivityManager.startCaptivePortalApp( startCaptivePortalApp(
mCaptivePortalNetworkCallback.getNetwork()); mCaptivePortalNetworkCallback.getNetwork());
} else { } else {
launchNetworkDetailsFragment(pref); launchNetworkDetailsFragment(pref);
@@ -914,7 +936,12 @@ public class WifiSettings extends RestrictedSettingsFragment
unregisterCaptivePortalNetworkCallback(); unregisterCaptivePortalNetworkCallback();
mCaptivePortalNetworkCallback = new CaptivePortalNetworkCallback(wifiNetwork, pref); mCaptivePortalNetworkCallback = new CaptivePortalNetworkCallback(wifiNetwork, pref) {
@Override
public void onCaptivePortalCapabilityChanged() {
checkStartCaptivePortalApp();
}
};
mConnectivityManager.registerNetworkCallback( mConnectivityManager.registerNetworkCallback(
new NetworkRequest.Builder() new NetworkRequest.Builder()
.clearCapabilities() .clearCapabilities()
@@ -1099,14 +1126,17 @@ public class WifiSettings extends RestrictedSettingsFragment
if (config == null) { if (config == null) {
if (mSelectedAccessPoint != null if (mSelectedAccessPoint != null
&& mSelectedAccessPoint.isSaved()) { && mSelectedAccessPoint.isSaved()) {
connect(mSelectedAccessPoint.getConfig(), true /* isSavedNetwork */); connect(mSelectedAccessPoint.getConfig(),
true /* isSavedNetwork */,
CONNECT_SOURCE_UNSPECIFIED);
} }
} else if (configController.getMode() == WifiConfigUiBase.MODE_MODIFY) { } else if (configController.getMode() == WifiConfigUiBase.MODE_MODIFY) {
mWifiManager.save(config, mSaveListener); mWifiManager.save(config, mSaveListener);
} else { } else {
mWifiManager.save(config, mSaveListener); mWifiManager.save(config, mSaveListener);
if (mSelectedAccessPoint != null) { // Not an "Add network" if (mSelectedAccessPoint != null) { // Not an "Add network"
connect(config, false /* isSavedNetwork */); connect(config, false /* isSavedNetwork */,
CONNECT_SOURCE_UNSPECIFIED);
} }
} }
@@ -1143,21 +1173,16 @@ public class WifiSettings extends RestrictedSettingsFragment
changeNextButtonState(false); changeNextButtonState(false);
} }
protected void connect(final WifiConfiguration config, boolean isSavedNetwork) { protected void connect(final WifiConfiguration config,
boolean isSavedNetwork, @ConnectSource int connectSource) {
// Log subtype if configuration is a saved network. // Log subtype if configuration is a saved network.
mMetricsFeatureProvider.action(getContext(), SettingsEnums.ACTION_WIFI_CONNECT, mMetricsFeatureProvider.action(getContext(), SettingsEnums.ACTION_WIFI_CONNECT,
isSavedNetwork); isSavedNetwork);
mConnectSource = connectSource;
mWifiManager.connect(config, mConnectListener); mWifiManager.connect(config, mConnectListener);
mClickedConnect = true; mClickedConnect = true;
} }
protected void connect(final int networkId, boolean isSavedNetwork) {
// Log subtype if configuration is a saved network.
mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_WIFI_CONNECT,
isSavedNetwork);
mWifiManager.connect(networkId, mConnectListener);
}
@VisibleForTesting @VisibleForTesting
void handleAddNetworkRequest(int result, Intent data) { void handleAddNetworkRequest(int result, Intent data) {
if (result == Activity.RESULT_OK) { if (result == Activity.RESULT_OK) {
@@ -1217,7 +1242,8 @@ public class WifiSettings extends RestrictedSettingsFragment
mWifiManager.save(wifiConfiguration, mSaveListener); mWifiManager.save(wifiConfiguration, mSaveListener);
if (mSelectedAccessPoint != null) { if (mSelectedAccessPoint != null) {
connect(wifiConfiguration, false /*isSavedNetwork*/); connect(wifiConfiguration, false /*isSavedNetwork*/,
CONNECT_SOURCE_UNSPECIFIED);
} }
mWifiTracker.resumeScanning(); mWifiTracker.resumeScanning();
} }
@@ -1236,6 +1262,42 @@ public class WifiSettings extends RestrictedSettingsFragment
.launch(); .launch();
} }
/**
* Starts the captive portal for current network if it's been clicked from the available
* networks (or contextual menu). We only do it *once* for a picked network, to avoid connecting
* again on bg/fg or if user dismisses Captive Portal before connecting (otherwise, coming back
* to this screen while connected to the same network but not signed in would open CP again).
*/
private void checkStartCaptivePortalApp() {
Network currentNetwork = getCurrentWifiNetwork();
if (mCaptivePortalNetworkCallback == null || currentNetwork == null
|| !currentNetwork.equals(mCaptivePortalNetworkCallback.getNetwork())
|| !mCaptivePortalNetworkCallback.isCaptivePortal()) {
return;
}
if (mConnectSource != CONNECT_SOURCE_NETWORK_LIST_ITEM_CLICK
&& mConnectSource != CONNECT_SOURCE_NETWORK_MENU_ITEM_CLICK) {
return;
}
if (mLastNetworkCaptivePortalAppStarted != null
&& mLastNetworkCaptivePortalAppStarted.equals(currentNetwork)) {
// We already auto-opened CP for same network
return;
}
startCaptivePortalApp(currentNetwork);
}
private void startCaptivePortalApp(Network network) {
if (mConnectivityManager == null || network == null) {
return;
}
mLastNetworkCaptivePortalAppStarted = network;
mConnectivityManager.startCaptivePortalApp(network);
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.wifi_settings) { new BaseSearchIndexProvider(R.xml.wifi_settings) {
@Override @Override

View File

@@ -15,6 +15,8 @@
*/ */
package com.android.settings.wifi; package com.android.settings.wifi;
import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
@@ -31,9 +33,14 @@ import android.app.Activity;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.wifi.EAPConstants; import android.net.wifi.EAPConstants;
import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import android.net.wifi.hotspot2.PasspointConfiguration; import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.Credential;
@@ -51,22 +58,30 @@ import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.datausage.DataUsagePreference; import com.android.settings.datausage.DataUsagePreference;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowDataUsageUtils; import com.android.settings.testutils.shadow.ShadowDataUsageUtils;
import com.android.settings.testutils.shadow.ShadowFragment; import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settings.widget.SwitchBar;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.wifi.AccessPoint; import com.android.settingslib.wifi.AccessPoint;
import com.android.settingslib.wifi.WifiTracker; import com.android.settingslib.wifi.WifiTracker;
import com.android.settingslib.wifi.WifiTrackerFactory;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@@ -81,9 +96,27 @@ public class WifiSettingsTest {
@Mock @Mock
private DataUsagePreference mDataUsagePreference; private DataUsagePreference mDataUsagePreference;
@Mock @Mock
private RecyclerView mRecyclerView;
@Mock
private RecyclerView.Adapter mRecyclerViewAdapter;
@Mock
private View mHeaderView;
@Mock
private WifiManager mWifiManager; private WifiManager mWifiManager;
@Mock
private ConnectivityManager mConnectivityManager;
@Mock
private Intent mActivityIntent;
@Mock
private SwitchBar mSwitchBar;
@Mock
private WifiInfo mWifiInfo;
@Mock
private PackageManager mPackageManager;
private Context mContext; private Context mContext;
private WifiSettings mWifiSettings; private WifiSettings mWifiSettings;
private FakeFeatureFactory mFakeFeatureFactory;
private MetricsFeatureProvider mMetricsFeatureProvider;
@Before @Before
public void setUp() { public void setUp() {
@@ -92,12 +125,23 @@ public class WifiSettingsTest {
mWifiSettings = spy(new WifiSettings()); mWifiSettings = spy(new WifiSettings());
doReturn(mContext).when(mWifiSettings).getContext(); doReturn(mContext).when(mWifiSettings).getContext();
doReturn(mRecyclerViewAdapter).when(mRecyclerView).getAdapter();
doReturn(mRecyclerView).when(mWifiSettings).getListView();
doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class); doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
doReturn(mHeaderView).when(mWifiSettings).setPinnedHeaderView(anyInt());
doReturn(mWifiInfo).when(mWifiManager).getConnectionInfo();
doReturn(mWifiManager).when(mWifiTracker).getManager();
mWifiSettings.mAddWifiNetworkPreference = new AddWifiNetworkPreference(mContext); mWifiSettings.mAddWifiNetworkPreference = new AddWifiNetworkPreference(mContext);
mWifiSettings.mSavedNetworksPreference = new Preference(mContext); mWifiSettings.mSavedNetworksPreference = new Preference(mContext);
mWifiSettings.mConfigureWifiSettingsPreference = new Preference(mContext); mWifiSettings.mConfigureWifiSettingsPreference = new Preference(mContext);
mWifiSettings.mWifiTracker = mWifiTracker; mWifiSettings.mWifiTracker = mWifiTracker;
mWifiSettings.mWifiManager = mWifiManager; mWifiSettings.mWifiManager = mWifiManager;
mWifiSettings.mConnectivityManager = mConnectivityManager;
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
mMetricsFeatureProvider = mFakeFeatureFactory.getMetricsFeatureProvider();
ReflectionHelpers.setField(mWifiSettings, "mMetricsFeatureProvider",
mMetricsFeatureProvider);
WifiTrackerFactory.setTestingWifiTracker(mWifiTracker);
} }
@Test @Test
@@ -138,6 +182,14 @@ public class WifiSettingsTest {
return mockConfigs; return mockConfigs;
} }
static NetworkCapabilities makeCaptivePortalNetworkCapabilities() {
final NetworkCapabilities capabilities = new NetworkCapabilities();
capabilities.clearAll();
capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
capabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
return capabilities;
}
@Test @Test
public void setAdditionalSettingsSummaries_hasSavedNetwork_preferenceVisible() { public void setAdditionalSettingsSummaries_hasSavedNetwork_preferenceVisible() {
when(mWifiManager.getConfiguredNetworks()) when(mWifiManager.getConfiguredNetworks())
@@ -225,16 +277,20 @@ public class WifiSettingsTest {
} }
private void setUpForOnCreate() { private void setUpForOnCreate() {
final FragmentActivity activity = mock(FragmentActivity.class); final SettingsActivity activity = mock(SettingsActivity.class);
when(activity.getSwitchBar()).thenReturn(mSwitchBar);
when(mWifiSettings.getActivity()).thenReturn(activity); when(mWifiSettings.getActivity()).thenReturn(activity);
final Resources.Theme theme = mContext.getTheme(); final Resources.Theme theme = mContext.getTheme();
when(activity.getTheme()).thenReturn(theme); when(activity.getTheme()).thenReturn(theme);
when(activity.getIntent()).thenReturn(mActivityIntent);
UserManager userManager = mock(UserManager.class); UserManager userManager = mock(UserManager.class);
when(activity.getSystemService(Context.USER_SERVICE)) when(activity.getSystemService(Context.USER_SERVICE))
.thenReturn(userManager); .thenReturn(userManager);
when(mWifiSettings.findPreference(WifiSettings.PREF_KEY_DATA_USAGE)) when(mWifiSettings.findPreference(WifiSettings.PREF_KEY_DATA_USAGE))
.thenReturn(mDataUsagePreference); .thenReturn(mDataUsagePreference);
when(activity.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
when(activity.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager);
when(activity.getPackageManager()).thenReturn(mPackageManager);
} }
@Test @Test
@@ -291,4 +347,58 @@ public class WifiSettingsTest {
assertThat(adapter.hasStableIds()).isTrue(); assertThat(adapter.hasStableIds()).isTrue();
} }
@Test
@Config(shadows = {ShadowDataUsageUtils.class, ShadowFragment.class})
public void clickOnWifiNetworkWith_shouldStartCaptivePortalApp() {
when(mWifiManager.getConfiguredNetworks()).thenReturn(createMockWifiConfigurations(
NUM_NETWORKS));
when(mWifiTracker.isConnected()).thenReturn(true);
final AccessPoint accessPointActive = mock(AccessPoint.class);
when(accessPointActive.isActive()).thenReturn(true);
when(accessPointActive.isSaved()).thenReturn(false);
when(accessPointActive.getConfig()).thenReturn(mock(WifiConfiguration.class));
final AccessPoint accessPointInactive = mock(AccessPoint.class);
when(accessPointInactive.isActive()).thenReturn(false);
when(accessPointInactive.isSaved()).thenReturn(false);
when(accessPointInactive.getConfig()).thenReturn(mock(WifiConfiguration.class));
when(mWifiTracker.getAccessPoints()).thenReturn(Arrays.asList(accessPointActive,
accessPointInactive));
when(mWifiManager.getWifiState()).thenReturn(WIFI_STATE_ENABLED);
when(mWifiManager.isWifiEnabled()).thenReturn(true);
final Network network = mock(Network.class);
when(mWifiManager.getCurrentNetwork()).thenReturn(network);
// Simulate activity creation cycle
setUpForOnCreate();
ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true;
mWifiSettings.onCreate(Bundle.EMPTY);
mWifiSettings.onActivityCreated(null);
mWifiSettings.onViewCreated(new View(mContext), new Bundle());
mWifiSettings.onStart();
// Click on open network
final Preference openWifiPref = new LongPressAccessPointPreference(accessPointInactive,
mContext, null,
false /* forSavedNetworks */, R.drawable.ic_wifi_signal_0,
null);
mWifiSettings.onPreferenceTreeClick(openWifiPref);
// Ensure connect() was called, and fake success.
ArgumentCaptor<WifiManager.ActionListener> wifiCallbackCaptor = ArgumentCaptor.forClass(
WifiManager.ActionListener.class);
verify(mWifiManager).connect(any(WifiConfiguration.class), wifiCallbackCaptor.capture());
wifiCallbackCaptor.getValue().onSuccess();
// Simulate capability change
mWifiSettings.mCaptivePortalNetworkCallback.onCapabilitiesChanged(network,
makeCaptivePortalNetworkCapabilities());
// Ensure CP was called
verify(mConnectivityManager).startCaptivePortalApp(eq(network));
}
} }