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;
/** Listens for changes to NetworkCapabilities to update the ConnectedAccessPointPreference. */
final class CaptivePortalNetworkCallback extends NetworkCallback {
class CaptivePortalNetworkCallback extends NetworkCallback {
private final ConnectedAccessPointPreference mConnectedApPreference;
private final Network mNetwork;
@@ -36,25 +36,42 @@ final class CaptivePortalNetworkCallback extends NetworkCallback {
}
@Override
public void onLost(Network network) {
public final void onLost(Network network) {
if (mNetwork.equals(network)) {
mIsCaptivePortal = false;
setIsCaptivePortal(false);
}
}
@Override
public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
public final void onCapabilitiesChanged(Network network,
NetworkCapabilities networkCapabilities) {
if (mNetwork.equals(network)) {
mIsCaptivePortal = WifiUtils.canSignIntoNetwork(networkCapabilities);
mConnectedApPreference.setCaptivePortal(mIsCaptivePortal);
boolean isCaptivePortal = WifiUtils.canSignIntoNetwork(networkCapabilities);
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
* originally supplied values.
*/
public boolean isSameNetworkAndPreference(
public final boolean isSameNetworkAndPreference(
Network network, ConnectedAccessPointPreference 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
* network and the Network was not lost in the interim.
*/
public boolean isCaptivePortal() {
public final boolean isCaptivePortal() {
return mIsCaptivePortal;
}
/** Returns the currently associated network. */
public Network getNetwork() {
public final Network getNetwork() {
return mNetwork;
}
}

View File

@@ -50,6 +50,7 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.IntDef;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
@@ -135,12 +136,16 @@ public class WifiSettings extends RestrictedSettingsFragment
setProgressBarVisible(false);
};
protected WifiManager mWifiManager;
private ConnectivityManager mConnectivityManager;
@VisibleForTesting
WifiManager mWifiManager;
@VisibleForTesting
ConnectivityManager mConnectivityManager;
private WifiManager.ActionListener mConnectListener;
private WifiManager.ActionListener mSaveListener;
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
@@ -196,6 +201,15 @@ public class WifiSettings extends RestrictedSettingsFragment
* network once connected.
*/
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" */
@@ -512,12 +526,14 @@ public class WifiSettings extends RestrictedSettingsFragment
case MENU_ID_CONNECT: {
boolean isSavedNetwork = mSelectedAccessPoint.isSaved();
if (isSavedNetwork) {
connect(mSelectedAccessPoint.getConfig(), isSavedNetwork);
connect(mSelectedAccessPoint.getConfig(), isSavedNetwork,
CONNECT_SOURCE_NETWORK_MENU_ITEM_CLICK);
} else if ((mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) ||
(mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_OWE)) {
/** Bypass dialog for unsecured networks */
mSelectedAccessPoint.generateOpenNetworkConfig();
connect(mSelectedAccessPoint.getConfig(), isSavedNetwork);
connect(mSelectedAccessPoint.getConfig(), isSavedNetwork,
CONNECT_SOURCE_NETWORK_MENU_ITEM_CLICK);
} else {
showDialog(mSelectedAccessPoint, WifiConfigUiBase.MODE_CONNECT);
}
@@ -563,11 +579,15 @@ public class WifiSettings extends RestrictedSettingsFragment
case WifiUtils.CONNECT_TYPE_OPEN_NETWORK:
mSelectedAccessPoint.generateOpenNetworkConfig();
connect(mSelectedAccessPoint.getConfig(), mSelectedAccessPoint.isSaved());
connect(mSelectedAccessPoint.getConfig(),
mSelectedAccessPoint.isSaved(),
CONNECT_SOURCE_NETWORK_LIST_ITEM_CLICK);
break;
case WifiUtils.CONNECT_TYPE_SAVED_NETWORK:
connect(mSelectedAccessPoint.getConfig(), true /* isSavedNetwork */);
connect(mSelectedAccessPoint.getConfig(),
true /* isSavedNetwork */,
CONNECT_SOURCE_NETWORK_LIST_ITEM_CLICK);
break;
default:
@@ -705,6 +725,8 @@ public class WifiSettings extends RestrictedSettingsFragment
setOffMessage();
setAdditionalSettingsSummaries();
setProgressBarVisible(false);
mConnectSource = CONNECT_SOURCE_UNSPECIFIED;
mClickedConnect = false;
break;
}
}
@@ -876,7 +898,7 @@ public class WifiSettings extends RestrictedSettingsFragment
pref.getAccessPoint().saveWifiState(pref.getExtras());
if (mCaptivePortalNetworkCallback != null
&& mCaptivePortalNetworkCallback.isCaptivePortal()) {
mConnectivityManager.startCaptivePortalApp(
startCaptivePortalApp(
mCaptivePortalNetworkCallback.getNetwork());
} else {
launchNetworkDetailsFragment(pref);
@@ -914,7 +936,12 @@ public class WifiSettings extends RestrictedSettingsFragment
unregisterCaptivePortalNetworkCallback();
mCaptivePortalNetworkCallback = new CaptivePortalNetworkCallback(wifiNetwork, pref);
mCaptivePortalNetworkCallback = new CaptivePortalNetworkCallback(wifiNetwork, pref) {
@Override
public void onCaptivePortalCapabilityChanged() {
checkStartCaptivePortalApp();
}
};
mConnectivityManager.registerNetworkCallback(
new NetworkRequest.Builder()
.clearCapabilities()
@@ -1099,14 +1126,17 @@ public class WifiSettings extends RestrictedSettingsFragment
if (config == null) {
if (mSelectedAccessPoint != null
&& mSelectedAccessPoint.isSaved()) {
connect(mSelectedAccessPoint.getConfig(), true /* isSavedNetwork */);
connect(mSelectedAccessPoint.getConfig(),
true /* isSavedNetwork */,
CONNECT_SOURCE_UNSPECIFIED);
}
} else if (configController.getMode() == WifiConfigUiBase.MODE_MODIFY) {
mWifiManager.save(config, mSaveListener);
} else {
mWifiManager.save(config, mSaveListener);
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);
}
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.
mMetricsFeatureProvider.action(getContext(), SettingsEnums.ACTION_WIFI_CONNECT,
isSavedNetwork);
mConnectSource = connectSource;
mWifiManager.connect(config, mConnectListener);
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
void handleAddNetworkRequest(int result, Intent data) {
if (result == Activity.RESULT_OK) {
@@ -1217,7 +1242,8 @@ public class WifiSettings extends RestrictedSettingsFragment
mWifiManager.save(wifiConfiguration, mSaveListener);
if (mSelectedAccessPoint != null) {
connect(wifiConfiguration, false /*isSavedNetwork*/);
connect(wifiConfiguration, false /*isSavedNetwork*/,
CONNECT_SOURCE_UNSPECIFIED);
}
mWifiTracker.resumeScanning();
}
@@ -1236,6 +1262,42 @@ public class WifiSettings extends RestrictedSettingsFragment
.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 =
new BaseSearchIndexProvider(R.xml.wifi_settings) {
@Override