Captive portal handling
We now notify the user of a captive portal before switching to the network as default. This allows background applications to continue to work until the user confirms he wants to sign in to the captive portal. Also, moved out captive portal handling out of wifi as a seperate component. Change-Id: I7c7507481967e33a1afad0b4961688bd192f0d31
This commit is contained in:
@@ -921,4 +921,15 @@ public class ConnectivityManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@hide}
|
||||||
|
*/
|
||||||
|
public void captivePortalCheckComplete(NetworkInfo info) {
|
||||||
|
try {
|
||||||
|
mService.captivePortalCheckComplete(info);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,4 +124,6 @@ interface IConnectivityManager
|
|||||||
LegacyVpnInfo getLegacyVpnInfo();
|
LegacyVpnInfo getLegacyVpnInfo();
|
||||||
|
|
||||||
boolean updateLockdownVpn();
|
boolean updateLockdownVpn();
|
||||||
|
|
||||||
|
void captivePortalCheckComplete(in NetworkInfo info);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,9 @@ public class NetworkInfo implements Parcelable {
|
|||||||
/** Access to this network is blocked. */
|
/** Access to this network is blocked. */
|
||||||
BLOCKED,
|
BLOCKED,
|
||||||
/** Link has poor connectivity. */
|
/** Link has poor connectivity. */
|
||||||
VERIFYING_POOR_LINK
|
VERIFYING_POOR_LINK,
|
||||||
|
/** Checking if network is a captive portal */
|
||||||
|
CAPTIVE_PORTAL_CHECK,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,6 +99,7 @@ public class NetworkInfo implements Parcelable {
|
|||||||
stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
|
stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
|
||||||
stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
|
stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
|
||||||
stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING);
|
stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING);
|
||||||
|
stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING);
|
||||||
stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
|
stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
|
||||||
stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
|
stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
|
||||||
stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
|
stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import android.content.IntentFilter;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
|
import android.net.CaptivePortalTracker;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.DummyDataStateTracker;
|
import android.net.DummyDataStateTracker;
|
||||||
import android.net.EthernetDataTracker;
|
import android.net.EthernetDataTracker;
|
||||||
@@ -166,6 +167,9 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
*/
|
*/
|
||||||
private NetworkStateTracker mNetTrackers[];
|
private NetworkStateTracker mNetTrackers[];
|
||||||
|
|
||||||
|
/* Handles captive portal check on a network */
|
||||||
|
private CaptivePortalTracker mCaptivePortalTracker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The link properties that define the current links
|
* The link properties that define the current links
|
||||||
*/
|
*/
|
||||||
@@ -1363,8 +1367,10 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
NetworkStateTracker tracker = mNetTrackers[networkType];
|
NetworkStateTracker tracker = mNetTrackers[networkType];
|
||||||
|
DetailedState netState = tracker.getNetworkInfo().getDetailedState();
|
||||||
|
|
||||||
if (tracker == null || !tracker.getNetworkInfo().isConnected() ||
|
if (tracker == null || (netState != DetailedState.CONNECTED &&
|
||||||
|
netState != DetailedState.CAPTIVE_PORTAL_CHECK) ||
|
||||||
tracker.isTeardownRequested()) {
|
tracker.isTeardownRequested()) {
|
||||||
if (VDBG) {
|
if (VDBG) {
|
||||||
log("requestRouteToHostAddress on down network " +
|
log("requestRouteToHostAddress on down network " +
|
||||||
@@ -1966,32 +1972,29 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private void handleConnect(NetworkInfo info) {
|
private boolean isNewNetTypePreferredOverCurrentNetType(int type) {
|
||||||
final int type = info.getType();
|
if ((type != mNetworkPreference &&
|
||||||
|
mNetConfigs[mActiveDefaultNetwork].priority >
|
||||||
|
mNetConfigs[type].priority) ||
|
||||||
|
mNetworkPreference == mActiveDefaultNetwork) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
setupDataActivityTracking(type);
|
private void handleConnect(NetworkInfo info) {
|
||||||
|
final int newNetType = info.getType();
|
||||||
|
|
||||||
|
setupDataActivityTracking(newNetType);
|
||||||
|
|
||||||
// snapshot isFailover, because sendConnectedBroadcast() resets it
|
// snapshot isFailover, because sendConnectedBroadcast() resets it
|
||||||
boolean isFailover = info.isFailover();
|
boolean isFailover = info.isFailover();
|
||||||
final NetworkStateTracker thisNet = mNetTrackers[type];
|
final NetworkStateTracker thisNet = mNetTrackers[newNetType];
|
||||||
final String thisIface = thisNet.getLinkProperties().getInterfaceName();
|
final String thisIface = thisNet.getLinkProperties().getInterfaceName();
|
||||||
|
|
||||||
// if this is a default net and other default is running
|
// if this is a default net and other default is running
|
||||||
// kill the one not preferred
|
// kill the one not preferred
|
||||||
if (mNetConfigs[type].isDefault()) {
|
if (mNetConfigs[newNetType].isDefault()) {
|
||||||
if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != type) {
|
if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != newNetType) {
|
||||||
if ((type != mNetworkPreference &&
|
if (isNewNetTypePreferredOverCurrentNetType(newNetType)) {
|
||||||
mNetConfigs[mActiveDefaultNetwork].priority >
|
|
||||||
mNetConfigs[type].priority) ||
|
|
||||||
mNetworkPreference == mActiveDefaultNetwork) {
|
|
||||||
// don't accept this one
|
|
||||||
if (VDBG) {
|
|
||||||
log("Not broadcasting CONNECT_ACTION " +
|
|
||||||
"to torn down network " + info.getTypeName());
|
|
||||||
}
|
|
||||||
teardown(thisNet);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// tear down the other
|
// tear down the other
|
||||||
NetworkStateTracker otherNet =
|
NetworkStateTracker otherNet =
|
||||||
mNetTrackers[mActiveDefaultNetwork];
|
mNetTrackers[mActiveDefaultNetwork];
|
||||||
@@ -2004,6 +2007,14 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
teardown(thisNet);
|
teardown(thisNet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// don't accept this one
|
||||||
|
if (VDBG) {
|
||||||
|
log("Not broadcasting CONNECT_ACTION " +
|
||||||
|
"to torn down network " + info.getTypeName());
|
||||||
|
}
|
||||||
|
teardown(thisNet);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
synchronized (ConnectivityService.this) {
|
synchronized (ConnectivityService.this) {
|
||||||
@@ -2017,7 +2028,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
1000);
|
1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mActiveDefaultNetwork = type;
|
mActiveDefaultNetwork = newNetType;
|
||||||
// this will cause us to come up initially as unconnected and switching
|
// this will cause us to come up initially as unconnected and switching
|
||||||
// to connected after our normal pause unless somebody reports us as reall
|
// to connected after our normal pause unless somebody reports us as reall
|
||||||
// disconnected
|
// disconnected
|
||||||
@@ -2029,19 +2040,47 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
}
|
}
|
||||||
thisNet.setTeardownRequested(false);
|
thisNet.setTeardownRequested(false);
|
||||||
updateNetworkSettings(thisNet);
|
updateNetworkSettings(thisNet);
|
||||||
handleConnectivityChange(type, false);
|
handleConnectivityChange(newNetType, false);
|
||||||
sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
|
sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
|
||||||
|
|
||||||
// notify battery stats service about this network
|
// notify battery stats service about this network
|
||||||
if (thisIface != null) {
|
if (thisIface != null) {
|
||||||
try {
|
try {
|
||||||
BatteryStatsService.getService().noteNetworkInterfaceType(thisIface, type);
|
BatteryStatsService.getService().noteNetworkInterfaceType(thisIface, newNetType);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// ignored; service lives in system_server
|
// ignored; service lives in system_server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleCaptivePortalTrackerCheck(NetworkInfo info) {
|
||||||
|
if (DBG) log("Captive portal check " + info);
|
||||||
|
int type = info.getType();
|
||||||
|
final NetworkStateTracker thisNet = mNetTrackers[type];
|
||||||
|
if (mNetConfigs[type].isDefault()) {
|
||||||
|
if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != type) {
|
||||||
|
if (isNewNetTypePreferredOverCurrentNetType(type)) {
|
||||||
|
if (DBG) log("Captive check on " + info.getTypeName());
|
||||||
|
mCaptivePortalTracker = CaptivePortalTracker.detect(mContext, info,
|
||||||
|
ConnectivityService.this);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (DBG) log("Tear down low priority net " + info.getTypeName());
|
||||||
|
teardown(thisNet);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thisNet.captivePortalCheckComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public void captivePortalCheckComplete(NetworkInfo info) {
|
||||||
|
mNetTrackers[info.getType()].captivePortalCheckComplete();
|
||||||
|
mCaptivePortalTracker = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup data activity tracking for the given network interface.
|
* Setup data activity tracking for the given network interface.
|
||||||
*
|
*
|
||||||
@@ -2630,6 +2669,9 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
if (info.getDetailedState() ==
|
if (info.getDetailedState() ==
|
||||||
NetworkInfo.DetailedState.FAILED) {
|
NetworkInfo.DetailedState.FAILED) {
|
||||||
handleConnectionFailure(info);
|
handleConnectionFailure(info);
|
||||||
|
} else if (info.getDetailedState() ==
|
||||||
|
DetailedState.CAPTIVE_PORTAL_CHECK) {
|
||||||
|
handleCaptivePortalTrackerCheck(info);
|
||||||
} else if (state == NetworkInfo.State.DISCONNECTED) {
|
} else if (state == NetworkInfo.State.DISCONNECTED) {
|
||||||
handleDisconnect(info);
|
handleDisconnect(info);
|
||||||
} else if (state == NetworkInfo.State.SUSPENDED) {
|
} else if (state == NetworkInfo.State.SUSPENDED) {
|
||||||
|
|||||||
Reference in New Issue
Block a user