Auto-open Captive Portal when user clicks on open network.
Rationale: many users are confused about what to do after tapping the captive portal network in Settings, and since there is explicit user action to connect to that network at that point, auto-opening the portal is natural and makes it simpler. Bug: 148538768 Test: manually with local AP with Captive Portal and: > make RunSettingsRoboTests -j40 > atest com.android.server.ConnectivityServiceTest Change-Id: I29573132cd3e46ff22e6f67bb3678516fabac47d
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.android.settings.wifi;
|
||||
|
||||
import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -31,9 +33,14 @@ import android.app.Activity;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
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.WifiConfiguration;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.net.wifi.hotspot2.PasspointConfiguration;
|
||||
import android.net.wifi.hotspot2.pps.Credential;
|
||||
@@ -51,22 +58,30 @@ import androidx.preference.PreferenceScreen;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
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.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.WifiTracker;
|
||||
import com.android.settingslib.wifi.WifiTrackerFactory;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -81,9 +96,27 @@ public class WifiSettingsTest {
|
||||
@Mock
|
||||
private DataUsagePreference mDataUsagePreference;
|
||||
@Mock
|
||||
private RecyclerView mRecyclerView;
|
||||
@Mock
|
||||
private RecyclerView.Adapter mRecyclerViewAdapter;
|
||||
@Mock
|
||||
private View mHeaderView;
|
||||
@Mock
|
||||
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 WifiSettings mWifiSettings;
|
||||
private FakeFeatureFactory mFakeFeatureFactory;
|
||||
private MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -92,12 +125,23 @@ public class WifiSettingsTest {
|
||||
|
||||
mWifiSettings = spy(new WifiSettings());
|
||||
doReturn(mContext).when(mWifiSettings).getContext();
|
||||
doReturn(mRecyclerViewAdapter).when(mRecyclerView).getAdapter();
|
||||
doReturn(mRecyclerView).when(mWifiSettings).getListView();
|
||||
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.mSavedNetworksPreference = new Preference(mContext);
|
||||
mWifiSettings.mConfigureWifiSettingsPreference = new Preference(mContext);
|
||||
mWifiSettings.mWifiTracker = mWifiTracker;
|
||||
mWifiSettings.mWifiManager = mWifiManager;
|
||||
mWifiSettings.mConnectivityManager = mConnectivityManager;
|
||||
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mMetricsFeatureProvider = mFakeFeatureFactory.getMetricsFeatureProvider();
|
||||
ReflectionHelpers.setField(mWifiSettings, "mMetricsFeatureProvider",
|
||||
mMetricsFeatureProvider);
|
||||
WifiTrackerFactory.setTestingWifiTracker(mWifiTracker);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -138,6 +182,14 @@ public class WifiSettingsTest {
|
||||
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
|
||||
public void setAdditionalSettingsSummaries_hasSavedNetwork_preferenceVisible() {
|
||||
when(mWifiManager.getConfiguredNetworks())
|
||||
@@ -225,16 +277,20 @@ public class WifiSettingsTest {
|
||||
}
|
||||
|
||||
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);
|
||||
final Resources.Theme theme = mContext.getTheme();
|
||||
when(activity.getTheme()).thenReturn(theme);
|
||||
when(activity.getIntent()).thenReturn(mActivityIntent);
|
||||
UserManager userManager = mock(UserManager.class);
|
||||
when(activity.getSystemService(Context.USER_SERVICE))
|
||||
.thenReturn(userManager);
|
||||
|
||||
when(mWifiSettings.findPreference(WifiSettings.PREF_KEY_DATA_USAGE))
|
||||
.thenReturn(mDataUsagePreference);
|
||||
when(activity.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
|
||||
when(activity.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager);
|
||||
when(activity.getPackageManager()).thenReturn(mPackageManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -291,4 +347,58 @@ public class WifiSettingsTest {
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user