Convert booleans in NAI to timestamps
These timestamps will be useful for debugging issues where debuggers need to know what happened to long-lived networks, where logcat doesn't span long enough. These timestamps are also likely to be useful in the future, in particular for metrics. Test: FrameworksNetTests Change-Id: I8f46ce92e2ab301fa32e18e714a43a4130719199
This commit is contained in:
@@ -1744,7 +1744,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
synchronized (mNetworkForNetId) {
|
synchronized (mNetworkForNetId) {
|
||||||
for (int i = 0; i < mNetworkForNetId.size(); i++) {
|
for (int i = 0; i < mNetworkForNetId.size(); i++) {
|
||||||
final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i);
|
final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i);
|
||||||
if (nai.isVPN() && nai.everConnected && nai.networkCapabilities.appliesToUid(uid)) {
|
if (nai.isVPN() && nai.everConnected()
|
||||||
|
&& nai.networkCapabilities.appliesToUid(uid)) {
|
||||||
return nai;
|
return nai;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2478,7 +2479,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
final ArrayList<NetworkStateSnapshot> result = new ArrayList<>();
|
final ArrayList<NetworkStateSnapshot> result = new ArrayList<>();
|
||||||
for (Network network : getAllNetworks()) {
|
for (Network network : getAllNetworks()) {
|
||||||
final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
|
final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
|
||||||
if (nai != null && nai.everConnected) {
|
if (nai != null && nai.everConnected()) {
|
||||||
// TODO (b/73321673) : NetworkStateSnapshot contains a copy of the
|
// TODO (b/73321673) : NetworkStateSnapshot contains a copy of the
|
||||||
// NetworkCapabilities, which may contain UIDs of apps to which the
|
// NetworkCapabilities, which may contain UIDs of apps to which the
|
||||||
// network applies. Should the UIDs be cleared so as not to leak or
|
// network applies. Should the UIDs be cleared so as not to leak or
|
||||||
@@ -3531,7 +3532,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the network has been destroyed, the only thing that it can do is disconnect.
|
// If the network has been destroyed, the only thing that it can do is disconnect.
|
||||||
if (nai.destroyed && !isDisconnectRequest(msg)) {
|
if (nai.isDestroyed() && !isDisconnectRequest(msg)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3560,7 +3561,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
|
case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
|
||||||
if (nai.everConnected) {
|
if (nai.everConnected()) {
|
||||||
loge("ERROR: cannot call explicitlySelected on already-connected network");
|
loge("ERROR: cannot call explicitlySelected on already-connected network");
|
||||||
// Note that if the NAI had been connected, this would affect the
|
// Note that if the NAI had been connected, this would affect the
|
||||||
// score, and therefore would require re-mixing the score and performing
|
// score, and therefore would require re-mixing the score and performing
|
||||||
@@ -3690,7 +3691,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
final int netId = msg.arg2;
|
final int netId = msg.arg2;
|
||||||
final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
|
final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
|
||||||
// If a network has already been destroyed, all NetworkMonitor updates are ignored.
|
// If a network has already been destroyed, all NetworkMonitor updates are ignored.
|
||||||
if (nai != null && nai.destroyed) return true;
|
if (nai != null && nai.isDestroyed()) return true;
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
@@ -3739,12 +3740,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
case EVENT_PROVISIONING_NOTIFICATION: {
|
case EVENT_PROVISIONING_NOTIFICATION: {
|
||||||
final boolean visible = toBool(msg.arg1);
|
final boolean visible = toBool(msg.arg1);
|
||||||
// If captive portal status has changed, update capabilities or disconnect.
|
// If captive portal status has changed, update capabilities or disconnect.
|
||||||
if (nai != null && (visible != nai.lastCaptivePortalDetected)) {
|
if (nai != null && (visible != nai.captivePortalDetected())) {
|
||||||
nai.lastCaptivePortalDetected = visible;
|
nai.setCaptivePortalDetected(visible);
|
||||||
nai.everCaptivePortalDetected |= visible;
|
if (visible && ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID
|
||||||
if (nai.lastCaptivePortalDetected &&
|
== getCaptivePortalMode()) {
|
||||||
ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID
|
|
||||||
== getCaptivePortalMode()) {
|
|
||||||
if (DBG) log("Avoiding captive portal network: " + nai.toShortString());
|
if (DBG) log("Avoiding captive portal network: " + nai.toShortString());
|
||||||
nai.onPreventAutomaticReconnect();
|
nai.onPreventAutomaticReconnect();
|
||||||
teardownUnneededNetwork(nai);
|
teardownUnneededNetwork(nai);
|
||||||
@@ -3796,11 +3795,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean wasValidated = nai.lastValidated;
|
final boolean wasValidated = nai.isValidated();
|
||||||
final boolean wasPartial = nai.partialConnectivity;
|
final boolean wasPartial = nai.partialConnectivity();
|
||||||
nai.partialConnectivity = ((testResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0);
|
nai.setPartialConnectivity((testResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0);
|
||||||
final boolean partialConnectivityChanged =
|
final boolean partialConnectivityChanged = (wasPartial != nai.partialConnectivity());
|
||||||
(wasPartial != nai.partialConnectivity);
|
|
||||||
|
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
final String logMsg = !TextUtils.isEmpty(redirectUrl)
|
final String logMsg = !TextUtils.isEmpty(redirectUrl)
|
||||||
@@ -3808,10 +3806,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
: "";
|
: "";
|
||||||
log(nai.toShortString() + " validation " + (valid ? "passed" : "failed") + logMsg);
|
log(nai.toShortString() + " validation " + (valid ? "passed" : "failed") + logMsg);
|
||||||
}
|
}
|
||||||
if (valid != nai.lastValidated) {
|
if (valid != nai.isValidated()) {
|
||||||
final FullScore oldScore = nai.getScore();
|
final FullScore oldScore = nai.getScore();
|
||||||
nai.lastValidated = valid;
|
nai.setValidated(valid);
|
||||||
nai.everValidated |= valid;
|
|
||||||
updateCapabilities(oldScore, nai, nai.networkCapabilities);
|
updateCapabilities(oldScore, nai, nai.networkCapabilities);
|
||||||
if (valid) {
|
if (valid) {
|
||||||
handleFreshlyValidatedNetwork(nai);
|
handleFreshlyValidatedNetwork(nai);
|
||||||
@@ -3844,13 +3841,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// EVENT_PROMPT_UNVALIDATED arrives, show the partial connectivity notification
|
// EVENT_PROMPT_UNVALIDATED arrives, show the partial connectivity notification
|
||||||
// immediately. Re-notify partial connectivity silently if no internet
|
// immediately. Re-notify partial connectivity silently if no internet
|
||||||
// notification already there.
|
// notification already there.
|
||||||
if (!wasPartial && nai.partialConnectivity) {
|
if (!wasPartial && nai.partialConnectivity()) {
|
||||||
// Remove delayed message if there is a pending message.
|
// Remove delayed message if there is a pending message.
|
||||||
mHandler.removeMessages(EVENT_PROMPT_UNVALIDATED, nai.network);
|
mHandler.removeMessages(EVENT_PROMPT_UNVALIDATED, nai.network);
|
||||||
handlePromptUnvalidated(nai.network);
|
handlePromptUnvalidated(nai.network);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wasValidated && !nai.lastValidated) {
|
if (wasValidated && !nai.isValidated()) {
|
||||||
handleNetworkUnvalidated(nai);
|
handleNetworkUnvalidated(nai);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4197,7 +4194,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean shouldDestroyNativeNetwork(@NonNull NetworkAgentInfo nai) {
|
private static boolean shouldDestroyNativeNetwork(@NonNull NetworkAgentInfo nai) {
|
||||||
return nai.created && !nai.destroyed;
|
return nai.isCreated() && !nai.isDestroyed();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldIgnoreValidationFailureAfterRoam(NetworkAgentInfo nai) {
|
private boolean shouldIgnoreValidationFailureAfterRoam(NetworkAgentInfo nai) {
|
||||||
@@ -4207,8 +4204,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
R.integer.config_validationFailureAfterRoamIgnoreTimeMillis));
|
R.integer.config_validationFailureAfterRoamIgnoreTimeMillis));
|
||||||
if (blockTimeOut <= MAX_VALIDATION_FAILURE_BLOCKING_TIME_MS
|
if (blockTimeOut <= MAX_VALIDATION_FAILURE_BLOCKING_TIME_MS
|
||||||
&& blockTimeOut >= 0) {
|
&& blockTimeOut >= 0) {
|
||||||
final long currentTimeMs = SystemClock.elapsedRealtime();
|
final long currentTimeMs = SystemClock.elapsedRealtime();
|
||||||
long timeSinceLastRoam = currentTimeMs - nai.lastRoamTimestamp;
|
long timeSinceLastRoam = currentTimeMs - nai.lastRoamTime;
|
||||||
if (timeSinceLastRoam <= blockTimeOut) {
|
if (timeSinceLastRoam <= blockTimeOut) {
|
||||||
log ("blocked because only " + timeSinceLastRoam + "ms after roam");
|
log ("blocked because only " + timeSinceLastRoam + "ms after roam");
|
||||||
return true;
|
return true;
|
||||||
@@ -4312,7 +4309,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delayed teardown.
|
// Delayed teardown.
|
||||||
if (nai.created) {
|
if (nai.isCreated()) {
|
||||||
try {
|
try {
|
||||||
mNetd.networkSetPermissionForNetwork(nai.network.netId, INetd.PERMISSION_SYSTEM);
|
mNetd.networkSetPermissionForNetwork(nai.network.netId, INetd.PERMISSION_SYSTEM);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -4333,7 +4330,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// for an unnecessarily long time.
|
// for an unnecessarily long time.
|
||||||
destroyNativeNetwork(nai);
|
destroyNativeNetwork(nai);
|
||||||
}
|
}
|
||||||
if (!nai.created && !SdkLevel.isAtLeastT()) {
|
if (!nai.isCreated() && !SdkLevel.isAtLeastT()) {
|
||||||
// Backwards compatibility: send onNetworkDestroyed even if network was never created.
|
// Backwards compatibility: send onNetworkDestroyed even if network was never created.
|
||||||
// This can never run if the code above runs because shouldDestroyNativeNetwork is
|
// This can never run if the code above runs because shouldDestroyNativeNetwork is
|
||||||
// false if the network was never created.
|
// false if the network was never created.
|
||||||
@@ -4394,11 +4391,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mDnsManager.removeNetwork(nai.network);
|
mDnsManager.removeNetwork(nai.network);
|
||||||
|
|
||||||
// clean up tc police filters on interface.
|
// clean up tc police filters on interface.
|
||||||
if (nai.everConnected && canNetworkBeRateLimited(nai) && mIngressRateLimit >= 0) {
|
if (nai.everConnected() && canNetworkBeRateLimited(nai) && mIngressRateLimit >= 0) {
|
||||||
mDeps.disableIngressRateLimit(nai.linkProperties.getInterfaceName());
|
mDeps.disableIngressRateLimit(nai.linkProperties.getInterfaceName());
|
||||||
}
|
}
|
||||||
|
|
||||||
nai.destroyed = true;
|
nai.setDestroyed();
|
||||||
nai.onNetworkDestroyed();
|
nai.onNetworkDestroyed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4527,7 +4524,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
|
private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
|
||||||
ensureRunningOnConnectivityServiceThread();
|
ensureRunningOnConnectivityServiceThread();
|
||||||
|
|
||||||
if (!nai.everConnected || nai.isVPN() || nai.isInactive()
|
if (!nai.everConnected() || nai.isVPN() || nai.isInactive()
|
||||||
|| nai.getScore().getKeepConnectedReason() != NetworkScore.KEEP_CONNECTED_NONE) {
|
|| nai.getScore().getKeepConnectedReason() != NetworkScore.KEEP_CONNECTED_NONE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -4859,7 +4856,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nai.everValidated) {
|
if (nai.everValidated()) {
|
||||||
// The network validated while the dialog box was up. Take no action.
|
// The network validated while the dialog box was up. Take no action.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -4904,7 +4901,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nai.lastValidated) {
|
if (nai.isValidated()) {
|
||||||
// The network validated while the dialog box was up. Take no action.
|
// The network validated while the dialog box was up. Take no action.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -4936,12 +4933,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
|
|
||||||
private void handleSetAvoidUnvalidated(Network network) {
|
private void handleSetAvoidUnvalidated(Network network) {
|
||||||
NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
|
NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
|
||||||
if (nai == null || nai.lastValidated) {
|
if (nai == null || nai.isValidated()) {
|
||||||
// Nothing to do. The network either disconnected or revalidated.
|
// Nothing to do. The network either disconnected or revalidated.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!nai.avoidUnvalidated) {
|
if (0L == nai.getAvoidUnvalidated()) {
|
||||||
nai.avoidUnvalidated = true;
|
nai.setAvoidUnvalidated();
|
||||||
nai.updateScoreForNetworkAgentUpdate();
|
nai.updateScoreForNetworkAgentUpdate();
|
||||||
rematchAllNetworksAndRequests();
|
rematchAllNetworksAndRequests();
|
||||||
}
|
}
|
||||||
@@ -5091,7 +5088,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
pw.println("Network overrides:");
|
pw.println("Network overrides:");
|
||||||
pw.increaseIndent();
|
pw.increaseIndent();
|
||||||
for (NetworkAgentInfo nai : networksSortedById()) {
|
for (NetworkAgentInfo nai : networksSortedById()) {
|
||||||
if (nai.avoidUnvalidated) {
|
if (0L != nai.getAvoidUnvalidated()) {
|
||||||
pw.println(nai.toShortString());
|
pw.println(nai.toShortString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5162,7 +5159,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) {
|
private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) {
|
||||||
// Don't prompt if the network is validated, and don't prompt on captive portals
|
// Don't prompt if the network is validated, and don't prompt on captive portals
|
||||||
// because we're already prompting the user to sign in.
|
// because we're already prompting the user to sign in.
|
||||||
if (nai.everValidated || nai.everCaptivePortalDetected) {
|
if (nai.everValidated() || nai.everCaptivePortalDetected()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5170,8 +5167,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// partial connectivity and selected don't ask again. This ensures that if the device
|
// partial connectivity and selected don't ask again. This ensures that if the device
|
||||||
// automatically connects to a network that has partial Internet access, the user will
|
// automatically connects to a network that has partial Internet access, the user will
|
||||||
// always be able to use it, either because they've already chosen "don't ask again" or
|
// always be able to use it, either because they've already chosen "don't ask again" or
|
||||||
// because we have prompt them.
|
// because we have prompted them.
|
||||||
if (nai.partialConnectivity && !nai.networkAgentConfig.acceptPartialConnectivity) {
|
if (nai.partialConnectivity() && !nai.networkAgentConfig.acceptPartialConnectivity) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5203,7 +5200,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// TODO: Evaluate if it's needed to wait 8 seconds for triggering notification when
|
// TODO: Evaluate if it's needed to wait 8 seconds for triggering notification when
|
||||||
// NetworkMonitor detects the network is partial connectivity. Need to change the design to
|
// NetworkMonitor detects the network is partial connectivity. Need to change the design to
|
||||||
// popup the notification immediately when the network is partial connectivity.
|
// popup the notification immediately when the network is partial connectivity.
|
||||||
if (nai.partialConnectivity) {
|
if (nai.partialConnectivity()) {
|
||||||
showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY);
|
showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY);
|
||||||
} else {
|
} else {
|
||||||
showNetworkNotification(nai, NotificationType.NO_INTERNET);
|
showNetworkNotification(nai, NotificationType.NO_INTERNET);
|
||||||
@@ -5557,7 +5554,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Revalidate if the app report does not match our current validated state.
|
// Revalidate if the app report does not match our current validated state.
|
||||||
if (hasConnectivity == nai.lastValidated) {
|
if (hasConnectivity == nai.isValidated()) {
|
||||||
mConnectivityDiagnosticsHandler.sendMessage(
|
mConnectivityDiagnosticsHandler.sendMessage(
|
||||||
mConnectivityDiagnosticsHandler.obtainMessage(
|
mConnectivityDiagnosticsHandler.obtainMessage(
|
||||||
ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED,
|
ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED,
|
||||||
@@ -5571,7 +5568,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
// Validating a network that has not yet connected could result in a call to
|
// Validating a network that has not yet connected could result in a call to
|
||||||
// rematchNetworkAndRequests() which is not meant to work on such networks.
|
// rematchNetworkAndRequests() which is not meant to work on such networks.
|
||||||
if (!nai.everConnected) {
|
if (!nai.everConnected()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
|
final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
|
||||||
@@ -7750,7 +7747,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
@NonNull final NetworkCapabilities newNc) {
|
@NonNull final NetworkCapabilities newNc) {
|
||||||
final int oldPermission = getNetworkPermission(nai.networkCapabilities);
|
final int oldPermission = getNetworkPermission(nai.networkCapabilities);
|
||||||
final int newPermission = getNetworkPermission(newNc);
|
final int newPermission = getNetworkPermission(newNc);
|
||||||
if (oldPermission != newPermission && nai.created && !nai.isVPN()) {
|
if (oldPermission != newPermission && nai.isCreated() && !nai.isVPN()) {
|
||||||
try {
|
try {
|
||||||
mNetd.networkSetPermissionForNetwork(nai.network.getNetId(), newPermission);
|
mNetd.networkSetPermissionForNetwork(nai.network.getNetId(), newPermission);
|
||||||
} catch (RemoteException | ServiceSpecificException e) {
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
@@ -7840,9 +7837,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// causing a connect/teardown loop.
|
// causing a connect/teardown loop.
|
||||||
// TODO: remove this altogether and make it the responsibility of the NetworkProviders to
|
// TODO: remove this altogether and make it the responsibility of the NetworkProviders to
|
||||||
// avoid connect/teardown loops.
|
// avoid connect/teardown loops.
|
||||||
if (nai.everConnected &&
|
if (nai.everConnected()
|
||||||
!nai.isVPN() &&
|
&& !nai.isVPN()
|
||||||
!nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) {
|
&& !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) {
|
||||||
// TODO: consider not complaining when a network agent degrades its capabilities if this
|
// TODO: consider not complaining when a network agent degrades its capabilities if this
|
||||||
// does not cause any request (that is not a listen) currently matching that agent to
|
// does not cause any request (that is not a listen) currently matching that agent to
|
||||||
// stop being matched by the updated agent.
|
// stop being matched by the updated agent.
|
||||||
@@ -7854,12 +7851,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
|
|
||||||
// Don't modify caller's NetworkCapabilities.
|
// Don't modify caller's NetworkCapabilities.
|
||||||
final NetworkCapabilities newNc = new NetworkCapabilities(nc);
|
final NetworkCapabilities newNc = new NetworkCapabilities(nc);
|
||||||
if (nai.lastValidated) {
|
if (nai.isValidated()) {
|
||||||
newNc.addCapability(NET_CAPABILITY_VALIDATED);
|
newNc.addCapability(NET_CAPABILITY_VALIDATED);
|
||||||
} else {
|
} else {
|
||||||
newNc.removeCapability(NET_CAPABILITY_VALIDATED);
|
newNc.removeCapability(NET_CAPABILITY_VALIDATED);
|
||||||
}
|
}
|
||||||
if (nai.lastCaptivePortalDetected) {
|
if (nai.captivePortalDetected()) {
|
||||||
newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
|
newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
|
||||||
} else {
|
} else {
|
||||||
newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
|
newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
|
||||||
@@ -7869,7 +7866,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
} else {
|
} else {
|
||||||
newNc.addCapability(NET_CAPABILITY_FOREGROUND);
|
newNc.addCapability(NET_CAPABILITY_FOREGROUND);
|
||||||
}
|
}
|
||||||
if (nai.partialConnectivity) {
|
if (nai.partialConnectivity()) {
|
||||||
newNc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
|
newNc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
|
||||||
} else {
|
} else {
|
||||||
newNc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
|
newNc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
|
||||||
@@ -8116,7 +8113,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// that happens to prevent false alarms.
|
// that happens to prevent false alarms.
|
||||||
final Set<UidRange> prevUids = prevNc == null ? null : prevNc.getUidRanges();
|
final Set<UidRange> prevUids = prevNc == null ? null : prevNc.getUidRanges();
|
||||||
final Set<UidRange> newUids = newNc == null ? null : newNc.getUidRanges();
|
final Set<UidRange> newUids = newNc == null ? null : newNc.getUidRanges();
|
||||||
if (nai.isVPN() && nai.everConnected && !UidRange.hasSameUids(prevUids, newUids)
|
if (nai.isVPN() && nai.everConnected() && !UidRange.hasSameUids(prevUids, newUids)
|
||||||
&& (nai.linkProperties.getHttpProxy() != null || isProxySetOnAnyDefaultNetwork())) {
|
&& (nai.linkProperties.getHttpProxy() != null || isProxySetOnAnyDefaultNetwork())) {
|
||||||
mProxyTracker.sendProxyBroadcast();
|
mProxyTracker.sendProxyBroadcast();
|
||||||
}
|
}
|
||||||
@@ -8236,8 +8233,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
if (VDBG || DDBG) {
|
if (VDBG || DDBG) {
|
||||||
log("Update of LinkProperties for " + nai.toShortString()
|
log("Update of LinkProperties for " + nai.toShortString()
|
||||||
+ "; created=" + nai.created
|
+ "; created=" + nai.getCreatedTime()
|
||||||
+ "; everConnected=" + nai.everConnected);
|
+ "; firstConnected=" + nai.getConnectedTime());
|
||||||
}
|
}
|
||||||
// TODO: eliminate this defensive copy after confirming that updateLinkProperties does not
|
// TODO: eliminate this defensive copy after confirming that updateLinkProperties does not
|
||||||
// modify its oldLp parameter.
|
// modify its oldLp parameter.
|
||||||
@@ -8669,7 +8666,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
previousSatisfier.removeRequest(previousRequest.requestId);
|
previousSatisfier.removeRequest(previousRequest.requestId);
|
||||||
if (canSupportGracefulNetworkSwitch(previousSatisfier, newSatisfier)
|
if (canSupportGracefulNetworkSwitch(previousSatisfier, newSatisfier)
|
||||||
&& !previousSatisfier.destroyed) {
|
&& !previousSatisfier.isDestroyed()) {
|
||||||
// If this network switch can't be supported gracefully, the request is not
|
// If this network switch can't be supported gracefully, the request is not
|
||||||
// lingered. This allows letting go of the network sooner to reclaim some
|
// lingered. This allows letting go of the network sooner to reclaim some
|
||||||
// performance on the new network, since the radio can't do both at the same
|
// performance on the new network, since the radio can't do both at the same
|
||||||
@@ -8937,7 +8934,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// The new default network can be newly null if and only if the old default
|
// The new default network can be newly null if and only if the old default
|
||||||
// network doesn't satisfy the default request any more because it lost a
|
// network doesn't satisfy the default request any more because it lost a
|
||||||
// capability.
|
// capability.
|
||||||
mDefaultInetConditionPublished = newDefaultNetwork.lastValidated ? 100 : 0;
|
mDefaultInetConditionPublished = newDefaultNetwork.isValidated() ? 100 : 0;
|
||||||
mLegacyTypeTracker.add(
|
mLegacyTypeTracker.add(
|
||||||
newDefaultNetwork.networkInfo.getType(), newDefaultNetwork);
|
newDefaultNetwork.networkInfo.getType(), newDefaultNetwork);
|
||||||
}
|
}
|
||||||
@@ -8958,7 +8955,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// they may get old info. Reverse this after the old startUsing api is removed.
|
// they may get old info. Reverse this after the old startUsing api is removed.
|
||||||
// This is on top of the multiple intent sequencing referenced in the todo above.
|
// This is on top of the multiple intent sequencing referenced in the todo above.
|
||||||
for (NetworkAgentInfo nai : nais) {
|
for (NetworkAgentInfo nai : nais) {
|
||||||
if (nai.everConnected) {
|
if (nai.everConnected()) {
|
||||||
addNetworkToLegacyTypeTracker(nai);
|
addNetworkToLegacyTypeTracker(nai);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9084,12 +9081,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
|
|
||||||
private void updateInetCondition(NetworkAgentInfo nai) {
|
private void updateInetCondition(NetworkAgentInfo nai) {
|
||||||
// Don't bother updating until we've graduated to validated at least once.
|
// Don't bother updating until we've graduated to validated at least once.
|
||||||
if (!nai.everValidated) return;
|
if (!nai.everValidated()) return;
|
||||||
// For now only update icons for the default connection.
|
// For now only update icons for the default connection.
|
||||||
// TODO: Update WiFi and cellular icons separately. b/17237507
|
// TODO: Update WiFi and cellular icons separately. b/17237507
|
||||||
if (!isDefaultNetwork(nai)) return;
|
if (!isDefaultNetwork(nai)) return;
|
||||||
|
|
||||||
int newInetCondition = nai.lastValidated ? 100 : 0;
|
int newInetCondition = nai.isValidated() ? 100 : 0;
|
||||||
// Don't repeat publish.
|
// Don't repeat publish.
|
||||||
if (newInetCondition == mDefaultInetConditionPublished) return;
|
if (newInetCondition == mDefaultInetConditionPublished) return;
|
||||||
|
|
||||||
@@ -9116,7 +9113,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// SUSPENDED state is currently only overridden from CONNECTED state. In the case the
|
// SUSPENDED state is currently only overridden from CONNECTED state. In the case the
|
||||||
// network agent is created, then goes to suspended, then goes out of suspended without
|
// network agent is created, then goes to suspended, then goes out of suspended without
|
||||||
// ever setting connected. Check if network agent is ever connected to update the state.
|
// ever setting connected. Check if network agent is ever connected to update the state.
|
||||||
newInfo.setDetailedState(nai.everConnected
|
newInfo.setDetailedState(nai.everConnected()
|
||||||
? NetworkInfo.DetailedState.CONNECTED
|
? NetworkInfo.DetailedState.CONNECTED
|
||||||
: NetworkInfo.DetailedState.CONNECTING,
|
: NetworkInfo.DetailedState.CONNECTING,
|
||||||
info.getReason(),
|
info.getReason(),
|
||||||
@@ -9141,7 +9138,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
+ oldInfo.getState() + " to " + state);
|
+ oldInfo.getState() + " to " + state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!networkAgent.created
|
if (!networkAgent.isCreated()
|
||||||
&& (state == NetworkInfo.State.CONNECTED
|
&& (state == NetworkInfo.State.CONNECTED
|
||||||
|| (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) {
|
|| (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) {
|
||||||
|
|
||||||
@@ -9155,13 +9152,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// anything happens to the network.
|
// anything happens to the network.
|
||||||
updateCapabilitiesForNetwork(networkAgent);
|
updateCapabilitiesForNetwork(networkAgent);
|
||||||
}
|
}
|
||||||
networkAgent.created = true;
|
networkAgent.setCreated();
|
||||||
networkAgent.onNetworkCreated();
|
networkAgent.onNetworkCreated();
|
||||||
updateAllowedUids(networkAgent, null, networkAgent.networkCapabilities);
|
updateAllowedUids(networkAgent, null, networkAgent.networkCapabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) {
|
if (!networkAgent.everConnected() && state == NetworkInfo.State.CONNECTED) {
|
||||||
networkAgent.everConnected = true;
|
networkAgent.setConnected();
|
||||||
|
|
||||||
// NetworkCapabilities need to be set before sending the private DNS config to
|
// NetworkCapabilities need to be set before sending the private DNS config to
|
||||||
// NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required.
|
// NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required.
|
||||||
@@ -9245,8 +9242,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// TODO(b/122649188): send the broadcast only to VPN users.
|
// TODO(b/122649188): send the broadcast only to VPN users.
|
||||||
mProxyTracker.sendProxyBroadcast();
|
mProxyTracker.sendProxyBroadcast();
|
||||||
}
|
}
|
||||||
} else if (networkAgent.created && (oldInfo.getState() == NetworkInfo.State.SUSPENDED ||
|
} else if (networkAgent.isCreated() && (oldInfo.getState() == NetworkInfo.State.SUSPENDED
|
||||||
state == NetworkInfo.State.SUSPENDED)) {
|
|| state == NetworkInfo.State.SUSPENDED)) {
|
||||||
mLegacyTypeTracker.update(networkAgent);
|
mLegacyTypeTracker.update(networkAgent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9674,7 +9671,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!TextUtils.equals(((WifiInfo)prevInfo).getBSSID(), ((WifiInfo)newInfo).getBSSID())) {
|
if (!TextUtils.equals(((WifiInfo)prevInfo).getBSSID(), ((WifiInfo)newInfo).getBSSID())) {
|
||||||
nai.lastRoamTimestamp = SystemClock.elapsedRealtime();
|
nai.lastRoamTime = SystemClock.elapsedRealtime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -229,8 +229,8 @@ public class LingerMonitor {
|
|||||||
@Nullable final NetworkAgentInfo toNai) {
|
@Nullable final NetworkAgentInfo toNai) {
|
||||||
if (VDBG) {
|
if (VDBG) {
|
||||||
Log.d(TAG, "noteLingerDefaultNetwork from=" + fromNai.toShortString()
|
Log.d(TAG, "noteLingerDefaultNetwork from=" + fromNai.toShortString()
|
||||||
+ " everValidated=" + fromNai.everValidated
|
+ " firstValidated=" + fromNai.getFirstValidationTime()
|
||||||
+ " lastValidated=" + fromNai.lastValidated
|
+ " lastValidated=" + fromNai.getCurrentValidationTime()
|
||||||
+ " to=" + toNai.toShortString());
|
+ " to=" + toNai.toShortString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,7 +253,7 @@ public class LingerMonitor {
|
|||||||
// 1. User connects to wireless printer.
|
// 1. User connects to wireless printer.
|
||||||
// 2. User turns on cellular data.
|
// 2. User turns on cellular data.
|
||||||
// 3. We show a notification.
|
// 3. We show a notification.
|
||||||
if (!fromNai.everValidated) return;
|
if (!fromNai.everValidated()) return;
|
||||||
|
|
||||||
// If this network is a captive portal, don't notify. This cannot happen on initial connect
|
// If this network is a captive portal, don't notify. This cannot happen on initial connect
|
||||||
// to a captive portal, because the everValidated check above will fail. However, it can
|
// to a captive portal, because the everValidated check above will fail. However, it can
|
||||||
@@ -286,7 +286,7 @@ public class LingerMonitor {
|
|||||||
// because its score changed.
|
// because its score changed.
|
||||||
// TODO: instead of just skipping notification, keep a note of it, and show it if it becomes
|
// TODO: instead of just skipping notification, keep a note of it, and show it if it becomes
|
||||||
// unvalidated.
|
// unvalidated.
|
||||||
if (fromNai.lastValidated) return;
|
if (fromNai.isValidated()) return;
|
||||||
|
|
||||||
if (!isNotificationEnabled(fromNai, toNai)) return;
|
if (!isNotificationEnabled(fromNai, toNai)) return;
|
||||||
|
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ public class Nat464Xlat {
|
|||||||
&& nai.netAgentConfig().skip464xlat;
|
&& nai.netAgentConfig().skip464xlat;
|
||||||
|
|
||||||
return (supported || isTestNetwork) && connected && isIpv6OnlyNetwork && !skip464xlat
|
return (supported || isTestNetwork) && connected && isIpv6OnlyNetwork && !skip464xlat
|
||||||
&& !nai.destroyed && (nai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)
|
&& !nai.isDestroyed() && (nai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)
|
||||||
? isCellular464XlatEnabled() : true);
|
? isCellular464XlatEnabled() : true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -189,42 +189,193 @@ public class NetworkAgentInfo implements NetworkRanker.Scoreable {
|
|||||||
// field instead.
|
// field instead.
|
||||||
private @Nullable NetworkCapabilities mDeclaredCapabilitiesUnsanitized;
|
private @Nullable NetworkCapabilities mDeclaredCapabilitiesUnsanitized;
|
||||||
|
|
||||||
// Indicates if netd has been told to create this Network. From this point on the appropriate
|
// Timestamp (SystemClock.elapsedRealtime()) when netd has been told to create this Network, or
|
||||||
// routing rules are setup and routes are added so packets can begin flowing over the Network.
|
// 0 if it hasn't been done yet.
|
||||||
// This is a sticky bit; once set it is never cleared.
|
// From this point on, the appropriate routing rules are setup and routes are added so packets
|
||||||
public boolean created;
|
// can begin flowing over the Network.
|
||||||
// Set to true after the first time this network is marked as CONNECTED. Once set, the network
|
// This is a sticky value; once set != 0 it is never changed.
|
||||||
// shows up in API calls, is able to satisfy NetworkRequests and can become the default network.
|
private long mCreatedTime;
|
||||||
// This is a sticky bit; once set it is never cleared.
|
|
||||||
public boolean everConnected;
|
|
||||||
// Whether this network has been destroyed and is being kept temporarily until it is replaced.
|
|
||||||
public boolean destroyed;
|
|
||||||
// To check how long it has been since last roam.
|
|
||||||
public long lastRoamTimestamp;
|
|
||||||
|
|
||||||
// Set to true if this Network successfully passed validation or if it did not satisfy the
|
/** Notify this NAI that netd was just told to create this network */
|
||||||
// default NetworkRequest in which case validation will not be attempted.
|
public void setCreated() {
|
||||||
// This is a sticky bit; once set it is never cleared even if future validation attempts fail.
|
if (0L != mCreatedTime) throw new IllegalStateException("Already created");
|
||||||
public boolean everValidated;
|
mCreatedTime = SystemClock.elapsedRealtime();
|
||||||
|
}
|
||||||
|
|
||||||
// The result of the last validation attempt on this network (true if validated, false if not).
|
/** Returns whether netd was told to create this network */
|
||||||
public boolean lastValidated;
|
public boolean isCreated() {
|
||||||
|
return mCreatedTime != 0L;
|
||||||
|
}
|
||||||
|
|
||||||
// If true, becoming unvalidated will lower the network's score. This is only meaningful if the
|
// Get the time (SystemClock.elapsedRealTime) when this network was created (or 0 if never).
|
||||||
// system is configured not to do this for certain networks, e.g., if the
|
public long getCreatedTime() {
|
||||||
// config_networkAvoidBadWifi option is set to 0 and the user has not overridden that via
|
return mCreatedTime;
|
||||||
// Settings.Global.NETWORK_AVOID_BAD_WIFI.
|
}
|
||||||
public boolean avoidUnvalidated;
|
|
||||||
|
|
||||||
// Whether a captive portal was ever detected on this network.
|
// Timestamp of the first time (SystemClock.elapsedRealtime()) this network is marked as
|
||||||
// This is a sticky bit; once set it is never cleared.
|
// connected, or 0 if this network has never been marked connected. Once set to non-zero, the
|
||||||
public boolean everCaptivePortalDetected;
|
// network shows up in API calls, is able to satisfy NetworkRequests and can become the default
|
||||||
|
// network.
|
||||||
|
// This is a sticky value; once set != 0 it is never changed.
|
||||||
|
private long mConnectedTime;
|
||||||
|
|
||||||
// Whether a captive portal was found during the last network validation attempt.
|
/** Notify this NAI that this network just connected */
|
||||||
public boolean lastCaptivePortalDetected;
|
public void setConnected() {
|
||||||
|
if (0L != mConnectedTime) throw new IllegalStateException("Already connected");
|
||||||
|
mConnectedTime = SystemClock.elapsedRealtime();
|
||||||
|
}
|
||||||
|
|
||||||
// Set to true when partial connectivity was detected.
|
/** Return whether this network ever connected */
|
||||||
public boolean partialConnectivity;
|
public boolean everConnected() {
|
||||||
|
return mConnectedTime != 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the time (SystemClock.elapsedRealTime()) when this network was first connected, or 0 if
|
||||||
|
// never.
|
||||||
|
public long getConnectedTime() {
|
||||||
|
return mConnectedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When this network has been destroyed and is being kept temporarily until it is replaced,
|
||||||
|
// this is set to that timestamp (SystemClock.elapsedRealtime()). Zero otherwise.
|
||||||
|
private long mDestroyedTime;
|
||||||
|
|
||||||
|
/** Notify this NAI that this network was destroyed */
|
||||||
|
public void setDestroyed() {
|
||||||
|
if (0L != mDestroyedTime) throw new IllegalStateException("Already destroyed");
|
||||||
|
mDestroyedTime = SystemClock.elapsedRealtime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return whether this network was destroyed */
|
||||||
|
public boolean isDestroyed() {
|
||||||
|
return 0L != mDestroyedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timestamp of the last roaming (SystemClock.elapsedRealtime()) or 0 if never roamed.
|
||||||
|
public long lastRoamTime;
|
||||||
|
|
||||||
|
// Timestamp (SystemClock.elapsedRealtime()) of the first time this network successfully
|
||||||
|
// passed validation or was deemed exempt of validation (see
|
||||||
|
// {@link NetworkMonitorUtils#isValidationRequired}). Zero if the network requires
|
||||||
|
// validation but never passed it successfully.
|
||||||
|
// This is a sticky value; once set it is never changed even if further validation attempts are
|
||||||
|
// made (whether they succeed or fail).
|
||||||
|
private long mFirstValidationTime;
|
||||||
|
|
||||||
|
// Timestamp (SystemClock.elapsedRealtime()) at which the latest validation attempt succeeded,
|
||||||
|
// or 0 if the latest validation attempt failed.
|
||||||
|
private long mCurrentValidationTime;
|
||||||
|
|
||||||
|
/** Notify this NAI that this network just finished a validation check */
|
||||||
|
public void setValidated(final boolean validated) {
|
||||||
|
final long nowOrZero = validated ? SystemClock.elapsedRealtime() : 0L;
|
||||||
|
if (validated && 0L == mFirstValidationTime) {
|
||||||
|
mFirstValidationTime = nowOrZero;
|
||||||
|
}
|
||||||
|
mCurrentValidationTime = nowOrZero;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this network is currently validated.
|
||||||
|
*
|
||||||
|
* This is the result of the latest validation check. {@see #getCurrentValidationTime} for
|
||||||
|
* when that check was performed.
|
||||||
|
*/
|
||||||
|
public boolean isValidated() {
|
||||||
|
return 0L != mCurrentValidationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this network ever passed the validation checks successfully.
|
||||||
|
*
|
||||||
|
* Note that the network may no longer be validated at this time ever if this is true.
|
||||||
|
* @see #isValidated
|
||||||
|
*/
|
||||||
|
public boolean everValidated() {
|
||||||
|
return 0L != mFirstValidationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the time (SystemClock.elapsedRealTime()) when this network was most recently validated,
|
||||||
|
// or 0 if this network was found not to validate on the last attempt.
|
||||||
|
public long getCurrentValidationTime() {
|
||||||
|
return mCurrentValidationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the time (SystemClock.elapsedRealTime()) when this network was validated for the first
|
||||||
|
// time (or 0 if never).
|
||||||
|
public long getFirstValidationTime() {
|
||||||
|
return mFirstValidationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timestamp (SystemClock.elapsedRealtime()) at which the user requested this network be
|
||||||
|
// avoided when unvalidated. Zero if this never happened for this network.
|
||||||
|
// This is only meaningful if the system is configured to have some cell networks yield
|
||||||
|
// to bad wifi, e.g., if the config_networkAvoidBadWifi option is set to 0 and the user has
|
||||||
|
// not overridden that via Settings.Global.NETWORK_AVOID_BAD_WIFI.
|
||||||
|
//
|
||||||
|
// Normally the system always prefers a validated network to a non-validated one, even if
|
||||||
|
// the non-validated one is cheaper. However, some cell networks may be configured by the
|
||||||
|
// setting above to yield to WiFi even if that WiFi network goes bad. When this configuration
|
||||||
|
// is active, specific networks can be marked to override this configuration so that the
|
||||||
|
// system will revert to preferring such a cell to this network when this network goes bad. This
|
||||||
|
// is achieved by calling {@link ConnectivityManager#setAvoidUnvalidated()}, and this field
|
||||||
|
// is set to non-zero when this happened to this network.
|
||||||
|
private long mAvoidUnvalidated;
|
||||||
|
|
||||||
|
/** Set this network as being avoided when unvalidated. {@see mAvoidUnvalidated} */
|
||||||
|
public void setAvoidUnvalidated() {
|
||||||
|
if (0L != mAvoidUnvalidated) throw new IllegalStateException("Already avoided unvalidated");
|
||||||
|
mAvoidUnvalidated = SystemClock.elapsedRealtime();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the time (SystemClock.elapsedRealTime()) when this network was set to being avoided
|
||||||
|
// when unvalidated, or 0 if this never happened.
|
||||||
|
public long getAvoidUnvalidated() {
|
||||||
|
return mAvoidUnvalidated;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timestamp (SystemClock.elapsedRealtime()) at which a captive portal was first detected
|
||||||
|
// on this network, or zero if this never happened.
|
||||||
|
// This is a sticky value; once set != 0 it is never changed.
|
||||||
|
private long mFirstCaptivePortalDetectedTime;
|
||||||
|
|
||||||
|
// Timestamp (SystemClock.elapsedRealtime()) at which the latest validation attempt found a
|
||||||
|
// captive portal, or zero if the latest attempt didn't find a captive portal.
|
||||||
|
private long mCurrentCaptivePortalDetectedTime;
|
||||||
|
|
||||||
|
/** Notify this NAI that a captive portal has just been detected on this network */
|
||||||
|
public void setCaptivePortalDetected(final boolean hasCaptivePortal) {
|
||||||
|
if (!hasCaptivePortal) {
|
||||||
|
mCurrentCaptivePortalDetectedTime = 0L;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final long now = SystemClock.elapsedRealtime();
|
||||||
|
if (0L == mFirstCaptivePortalDetectedTime) mFirstCaptivePortalDetectedTime = now;
|
||||||
|
mCurrentCaptivePortalDetectedTime = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return whether a captive portal has ever been detected on this network */
|
||||||
|
public boolean everCaptivePortalDetected() {
|
||||||
|
return 0L != mFirstCaptivePortalDetectedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return whether this network has been detected to be behind a captive portal at the moment */
|
||||||
|
public boolean captivePortalDetected() {
|
||||||
|
return 0L != mCurrentCaptivePortalDetectedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timestamp (SystemClock.elapsedRealtime()) at which the latest validation attempt found
|
||||||
|
// partial connectivity, or zero if the latest attempt didn't find partial connectivity.
|
||||||
|
private long mPartialConnectivityTime;
|
||||||
|
|
||||||
|
public void setPartialConnectivity(final boolean value) {
|
||||||
|
mPartialConnectivityTime = value ? SystemClock.elapsedRealtime() : 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return whether this NAI has partial connectivity */
|
||||||
|
public boolean partialConnectivity() {
|
||||||
|
return 0L != mPartialConnectivityTime;
|
||||||
|
}
|
||||||
|
|
||||||
// Delay between when the network is disconnected and when the native network is destroyed.
|
// Delay between when the network is disconnected and when the native network is destroyed.
|
||||||
public int teardownDelayMs;
|
public int teardownDelayMs;
|
||||||
@@ -820,7 +971,7 @@ public class NetworkAgentInfo implements NetworkRanker.Scoreable {
|
|||||||
final NetworkCapabilities oldNc = networkCapabilities;
|
final NetworkCapabilities oldNc = networkCapabilities;
|
||||||
networkCapabilities = nc;
|
networkCapabilities = nc;
|
||||||
mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig, everValidatedForYield(),
|
mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig, everValidatedForYield(),
|
||||||
yieldToBadWiFi(), destroyed);
|
yieldToBadWiFi(), isDestroyed());
|
||||||
final NetworkMonitorManager nm = mNetworkMonitor;
|
final NetworkMonitorManager nm = mNetworkMonitor;
|
||||||
if (nm != null) {
|
if (nm != null) {
|
||||||
nm.notifyNetworkCapabilitiesChanged(nc);
|
nm.notifyNetworkCapabilitiesChanged(nc);
|
||||||
@@ -983,13 +1134,14 @@ public class NetworkAgentInfo implements NetworkRanker.Scoreable {
|
|||||||
|
|
||||||
// Does this network satisfy request?
|
// Does this network satisfy request?
|
||||||
public boolean satisfies(NetworkRequest request) {
|
public boolean satisfies(NetworkRequest request) {
|
||||||
return everConnected
|
return everConnected()
|
||||||
&& request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities);
|
&& request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean satisfiesImmutableCapabilitiesOf(NetworkRequest request) {
|
public boolean satisfiesImmutableCapabilitiesOf(NetworkRequest request) {
|
||||||
return everConnected && request.networkCapabilities.satisfiedByImmutableNetworkCapabilities(
|
return everConnected()
|
||||||
networkCapabilities);
|
&& request.networkCapabilities.satisfiedByImmutableNetworkCapabilities(
|
||||||
|
networkCapabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this network is a VPN. */
|
/** Whether this network is a VPN. */
|
||||||
@@ -1022,7 +1174,7 @@ public class NetworkAgentInfo implements NetworkRanker.Scoreable {
|
|||||||
*/
|
*/
|
||||||
public void setScore(final NetworkScore score) {
|
public void setScore(final NetworkScore score) {
|
||||||
mScore = FullScore.fromNetworkScore(score, networkCapabilities, networkAgentConfig,
|
mScore = FullScore.fromNetworkScore(score, networkCapabilities, networkAgentConfig,
|
||||||
everValidatedForYield(), yieldToBadWiFi(), destroyed);
|
everValidatedForYield(), yieldToBadWiFi(), isDestroyed());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1032,11 +1184,11 @@ public class NetworkAgentInfo implements NetworkRanker.Scoreable {
|
|||||||
*/
|
*/
|
||||||
public void updateScoreForNetworkAgentUpdate() {
|
public void updateScoreForNetworkAgentUpdate() {
|
||||||
mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig,
|
mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig,
|
||||||
everValidatedForYield(), yieldToBadWiFi(), destroyed);
|
everValidatedForYield(), yieldToBadWiFi(), isDestroyed());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean everValidatedForYield() {
|
private boolean everValidatedForYield() {
|
||||||
return everValidated && !avoidUnvalidated;
|
return everValidated() && 0L == mAvoidUnvalidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1323,14 +1475,17 @@ public class NetworkAgentInfo implements NetworkRanker.Scoreable {
|
|||||||
+ networkInfo.toShortString() + "} "
|
+ networkInfo.toShortString() + "} "
|
||||||
+ "created=" + Instant.ofEpochMilli(mCreationTime) + " "
|
+ "created=" + Instant.ofEpochMilli(mCreationTime) + " "
|
||||||
+ mScore + " "
|
+ mScore + " "
|
||||||
+ (created ? " created" : "")
|
+ (isCreated() ? " created " + getCreatedTime() : "")
|
||||||
+ (destroyed ? " destroyed" : "")
|
+ (isDestroyed() ? " destroyed " + mDestroyedTime : "")
|
||||||
+ (isNascent() ? " nascent" : (isLingering() ? " lingering" : ""))
|
+ (isNascent() ? " nascent" : (isLingering() ? " lingering" : ""))
|
||||||
+ (everValidated ? " everValidated" : "")
|
+ (everValidated() ? " firstValidated " + getFirstValidationTime() : "")
|
||||||
+ (lastValidated ? " lastValidated" : "")
|
+ (isValidated() ? " lastValidated " + getCurrentValidationTime() : "")
|
||||||
+ (partialConnectivity ? " partialConnectivity" : "")
|
+ (partialConnectivity()
|
||||||
+ (everCaptivePortalDetected ? " everCaptivePortal" : "")
|
? " partialConnectivity " + mPartialConnectivityTime : "")
|
||||||
+ (lastCaptivePortalDetected ? " isCaptivePortal" : "")
|
+ (everCaptivePortalDetected()
|
||||||
|
? " firstCaptivePortalDetected " + mFirstCaptivePortalDetectedTime : "")
|
||||||
|
+ (captivePortalDetected()
|
||||||
|
? " currentCaptivePortalDetected " + mCurrentCaptivePortalDetectedTime : "")
|
||||||
+ (networkAgentConfig.explicitlySelected ? " explicitlySelected" : "")
|
+ (networkAgentConfig.explicitlySelected ? " explicitlySelected" : "")
|
||||||
+ (networkAgentConfig.acceptUnvalidated ? " acceptUnvalidated" : "")
|
+ (networkAgentConfig.acceptUnvalidated ? " acceptUnvalidated" : "")
|
||||||
+ (networkAgentConfig.acceptPartialConnectivity ? " acceptPartialConnectivity" : "")
|
+ (networkAgentConfig.acceptPartialConnectivity ? " acceptPartialConnectivity" : "")
|
||||||
@@ -1348,7 +1503,7 @@ public class NetworkAgentInfo implements NetworkRanker.Scoreable {
|
|||||||
*
|
*
|
||||||
* This is often not enough for debugging purposes for anything complex, but the full form
|
* This is often not enough for debugging purposes for anything complex, but the full form
|
||||||
* is very long and hard to read, so this is useful when there isn't a lot of ambiguity.
|
* is very long and hard to read, so this is useful when there isn't a lot of ambiguity.
|
||||||
* This represents the network with something like "[100 WIFI|VPN]" or "[108 MOBILE]".
|
* This represents the network with something like "[100 WIFI|VPN]" or "[108 CELLULAR]".
|
||||||
*/
|
*/
|
||||||
public String toShortString() {
|
public String toShortString() {
|
||||||
return "[" + network.getNetId() + " "
|
return "[" + network.getNetId() + " "
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertEquals;
|
|||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -47,6 +48,7 @@ import android.net.metrics.RaEvent;
|
|||||||
import android.net.metrics.ValidationProbeEvent;
|
import android.net.metrics.ValidationProbeEvent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.system.OsConstants;
|
import android.system.OsConstants;
|
||||||
import android.test.suitebuilder.annotation.SmallTest;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
@@ -138,7 +140,7 @@ public class IpConnectivityMetricsTest {
|
|||||||
private void logDefaultNetworkEvent(long timeMs, NetworkAgentInfo nai,
|
private void logDefaultNetworkEvent(long timeMs, NetworkAgentInfo nai,
|
||||||
NetworkAgentInfo oldNai) {
|
NetworkAgentInfo oldNai) {
|
||||||
final Network network = (nai != null) ? nai.network() : null;
|
final Network network = (nai != null) ? nai.network() : null;
|
||||||
final boolean validated = (nai != null) ? nai.lastValidated : false;
|
final boolean validated = (nai != null) ? nai.isValidated() : false;
|
||||||
final LinkProperties lp = (nai != null) ? nai.linkProperties : null;
|
final LinkProperties lp = (nai != null) ? nai.linkProperties : null;
|
||||||
final NetworkCapabilities nc = (nai != null) ? nai.networkCapabilities : null;
|
final NetworkCapabilities nc = (nai != null) ? nai.networkCapabilities : null;
|
||||||
|
|
||||||
@@ -614,7 +616,10 @@ public class IpConnectivityMetricsTest {
|
|||||||
when(nai.network()).thenReturn(new Network(netId));
|
when(nai.network()).thenReturn(new Network(netId));
|
||||||
nai.linkProperties = new LinkProperties();
|
nai.linkProperties = new LinkProperties();
|
||||||
nai.networkCapabilities = new NetworkCapabilities();
|
nai.networkCapabilities = new NetworkCapabilities();
|
||||||
nai.lastValidated = true;
|
nai.setValidated(true);
|
||||||
|
doReturn(true).when(nai).isValidated();
|
||||||
|
doReturn(SystemClock.elapsedRealtime()).when(nai).getFirstValidationTime();
|
||||||
|
doReturn(SystemClock.elapsedRealtime()).when(nai).getCurrentValidationTime();
|
||||||
for (int t : BitUtils.unpackBits(transports)) {
|
for (int t : BitUtils.unpackBits(transports)) {
|
||||||
nai.networkCapabilities.addTransportType(t);
|
nai.networkCapabilities.addTransportType(t);
|
||||||
}
|
}
|
||||||
@@ -629,8 +634,6 @@ public class IpConnectivityMetricsTest {
|
|||||||
return nai;
|
return nai;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void verifySerialization(String want, String output) {
|
static void verifySerialization(String want, String output) {
|
||||||
try {
|
try {
|
||||||
byte[] got = Base64.decode(output, Base64.DEFAULT);
|
byte[] got = Base64.decode(output, Base64.DEFAULT);
|
||||||
|
|||||||
@@ -272,9 +272,8 @@ public class LingerMonitorTest {
|
|||||||
public void testIgnoreNeverValidatedNetworks() {
|
public void testIgnoreNeverValidatedNetworks() {
|
||||||
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
|
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
|
||||||
setNotificationSwitch(transition(WIFI, CELLULAR));
|
setNotificationSwitch(transition(WIFI, CELLULAR));
|
||||||
NetworkAgentInfo from = wifiNai(100);
|
NetworkAgentInfo from = wifiNai(100, false /* setEverValidated */);
|
||||||
NetworkAgentInfo to = cellNai(101);
|
NetworkAgentInfo to = cellNai(101);
|
||||||
from.everValidated = false;
|
|
||||||
|
|
||||||
mMonitor.noteLingerDefaultNetwork(from, to);
|
mMonitor.noteLingerDefaultNetwork(from, to);
|
||||||
verifyNoNotifications();
|
verifyNoNotifications();
|
||||||
@@ -286,7 +285,7 @@ public class LingerMonitorTest {
|
|||||||
setNotificationSwitch(transition(WIFI, CELLULAR));
|
setNotificationSwitch(transition(WIFI, CELLULAR));
|
||||||
NetworkAgentInfo from = wifiNai(100);
|
NetworkAgentInfo from = wifiNai(100);
|
||||||
NetworkAgentInfo to = cellNai(101);
|
NetworkAgentInfo to = cellNai(101);
|
||||||
from.lastValidated = true;
|
from.setValidated(true);
|
||||||
|
|
||||||
mMonitor.noteLingerDefaultNetwork(from, to);
|
mMonitor.noteLingerDefaultNetwork(from, to);
|
||||||
verifyNoNotifications();
|
verifyNoNotifications();
|
||||||
@@ -363,7 +362,8 @@ public class LingerMonitorTest {
|
|||||||
eq(NotificationType.NETWORK_SWITCH), eq(from), eq(to), any(), eq(true));
|
eq(NotificationType.NETWORK_SWITCH), eq(from), eq(to), any(), eq(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkAgentInfo nai(int netId, int transport, int networkType, String networkTypeName) {
|
NetworkAgentInfo nai(int netId, int transport, int networkType, String networkTypeName,
|
||||||
|
boolean setEverValidated) {
|
||||||
NetworkInfo info = new NetworkInfo(networkType, 0, networkTypeName, "");
|
NetworkInfo info = new NetworkInfo(networkType, 0, networkTypeName, "");
|
||||||
NetworkCapabilities caps = new NetworkCapabilities();
|
NetworkCapabilities caps = new NetworkCapabilities();
|
||||||
caps.addCapability(0);
|
caps.addCapability(0);
|
||||||
@@ -373,18 +373,32 @@ public class LingerMonitorTest {
|
|||||||
mCtx, null, new NetworkAgentConfig.Builder().build(), mConnService, mNetd,
|
mCtx, null, new NetworkAgentConfig.Builder().build(), mConnService, mNetd,
|
||||||
mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(), TEST_LINGER_DELAY_MS,
|
mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(), TEST_LINGER_DELAY_MS,
|
||||||
mQosCallbackTracker, new ConnectivityService.Dependencies());
|
mQosCallbackTracker, new ConnectivityService.Dependencies());
|
||||||
nai.everValidated = true;
|
if (setEverValidated) {
|
||||||
|
// As tests in this class deal with testing lingering, most tests are interested
|
||||||
|
// in networks that can be lingered, and therefore must have validated in the past.
|
||||||
|
// Thus, pretend the network validated once, then became invalidated.
|
||||||
|
nai.setValidated(true);
|
||||||
|
nai.setValidated(false);
|
||||||
|
}
|
||||||
return nai;
|
return nai;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkAgentInfo wifiNai(int netId) {
|
NetworkAgentInfo wifiNai(int netId) {
|
||||||
|
return wifiNai(netId, true /* setEverValidated */);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkAgentInfo wifiNai(int netId, boolean setEverValidated) {
|
||||||
return nai(netId, NetworkCapabilities.TRANSPORT_WIFI,
|
return nai(netId, NetworkCapabilities.TRANSPORT_WIFI,
|
||||||
ConnectivityManager.TYPE_WIFI, WIFI);
|
ConnectivityManager.TYPE_WIFI, WIFI, setEverValidated);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkAgentInfo cellNai(int netId) {
|
NetworkAgentInfo cellNai(int netId) {
|
||||||
|
return cellNai(netId, true /* setEverValidated */);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkAgentInfo cellNai(int netId, boolean setEverValidated) {
|
||||||
return nai(netId, NetworkCapabilities.TRANSPORT_CELLULAR,
|
return nai(netId, NetworkCapabilities.TRANSPORT_CELLULAR,
|
||||||
ConnectivityManager.TYPE_MOBILE, CELLULAR);
|
ConnectivityManager.TYPE_MOBILE, CELLULAR, setEverValidated);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TestableLingerMonitor extends LingerMonitor {
|
public static class TestableLingerMonitor extends LingerMonitor {
|
||||||
|
|||||||
Reference in New Issue
Block a user