[NS A43] Separate updating the linger timer and sending LOSING

This will be necessary because updating the linger timer is
what lets the network agent know whether the network is

Test: ConnectivityServiceTest
Change-Id: I9b5a36f6d5eac5a404eff6740cd8f4dcbb0c2786
This commit is contained in:
Chalard Jean
2019-12-04 18:49:18 +09:00
parent 383f5ef79a
commit 8fd82aea7e

View File

@@ -3097,7 +3097,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
} }
private void updateLingerState(NetworkAgentInfo nai, long now) { /**
* Updates the linger state from the network requests inside the NAI.
* @param nai the agent info to update
* @param now the timestamp of the event causing this update
* @return whether the network was lingered as a result of this update
*/
private boolean updateLingerState(@NonNull final NetworkAgentInfo nai, final long now) {
// 1. Update the linger timer. If it's changed, reschedule or cancel the alarm. // 1. Update the linger timer. If it's changed, reschedule or cancel the alarm.
// 2. If the network was lingering and there are now requests, unlinger it. // 2. If the network was lingering and there are now requests, unlinger it.
// 3. If this network is unneeded (which implies it is not lingering), and there is at least // 3. If this network is unneeded (which implies it is not lingering), and there is at least
@@ -3108,12 +3114,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
nai.unlinger(); nai.unlinger();
logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER); logNetworkEvent(nai, NetworkEvent.NETWORK_UNLINGER);
} else if (unneeded(nai, UnneededFor.LINGER) && nai.getLingerExpiry() > 0) { } else if (unneeded(nai, UnneededFor.LINGER) && nai.getLingerExpiry() > 0) {
int lingerTime = (int) (nai.getLingerExpiry() - now); if (DBG) {
if (DBG) log("Lingering " + nai.name() + " for " + lingerTime + "ms"); final int lingerTime = (int) (nai.getLingerExpiry() - now);
log("Lingering " + nai.name() + " for " + lingerTime + "ms");
}
nai.linger(); nai.linger();
logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER); logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER);
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime); return true;
} }
return false;
} }
private void handleAsyncChannelHalfConnect(Message msg) { private void handleAsyncChannelHalfConnect(Message msg) {
@@ -3457,7 +3466,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
// If there are still lingered requests on this network, don't tear it down, // If there are still lingered requests on this network, don't tear it down,
// but resume lingering instead. // but resume lingering instead.
updateLingerState(nai, SystemClock.elapsedRealtime()); final long now = SystemClock.elapsedRealtime();
if (updateLingerState(nai, now)) {
notifyNetworkLosing(nai, now);
}
if (unneeded(nai, UnneededFor.TEARDOWN)) { if (unneeded(nai, UnneededFor.TEARDOWN)) {
if (DBG) log("no live requests for " + nai.name() + "; disconnecting"); if (DBG) log("no live requests for " + nai.name() + "; disconnecting");
teardownUnneededNetwork(nai); teardownUnneededNetwork(nai);
@@ -6600,6 +6612,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
nri, currentNetwork, null)); nri, currentNetwork, null));
} }
} }
return reassignedRequests; return reassignedRequests;
} }
@@ -6746,13 +6759,20 @@ public class ConnectivityService extends IConnectivityManager.Stub
processNewlySatisfiedListenRequests(event.mNetwork); processNewlySatisfiedListenRequests(event.mNetwork);
} }
final ArrayList<NetworkAgentInfo> lingeredNetworks = new ArrayList<>();
for (final NetworkAgentInfo nai : nais) { for (final NetworkAgentInfo nai : nais) {
// Rematching may have altered the linger state of some networks, so update all linger // Rematching may have altered the linger state of some networks, so update all linger
// timers. updateLingerState reads the state from the network agent and does nothing // timers. updateLingerState reads the state from the network agent and does nothing
// if the state has not changed : the source of truth is controlled with // if the state has not changed : the source of truth is controlled with
// NetworkAgentInfo#lingerRequest and NetworkAgentInfo#unlingerRequest, which have been // NetworkAgentInfo#lingerRequest and NetworkAgentInfo#unlingerRequest, which have been
// called while rematching the individual networks above. // called while rematching the individual networks above.
updateLingerState(nai, now); if (updateLingerState(nai, now)) {
lingeredNetworks.add(nai);
}
}
for (final NetworkAgentInfo nai : lingeredNetworks) {
notifyNetworkLosing(nai, now);
} }
updateLegacyTypeTrackerAndVpnLockdownForRematch(oldDefaultNetwork, newDefaultNetwork, nais); updateLegacyTypeTrackerAndVpnLockdownForRematch(oldDefaultNetwork, newDefaultNetwork, nais);
@@ -6768,7 +6788,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
// and became unneeded due to another network improving its score to the // and became unneeded due to another network improving its score to the
// point where this network will no longer be able to satisfy any requests // point where this network will no longer be able to satisfy any requests
// even if it validates. // even if it validates.
updateLingerState(nai, now); if (updateLingerState(nai, now)) {
notifyNetworkLosing(nai, now);
}
} else { } else {
if (DBG) log("Reaping " + nai.name()); if (DBG) log("Reaping " + nai.name());
teardownUnneededNetwork(nai); teardownUnneededNetwork(nai);
@@ -7021,6 +7043,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0); callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0);
} }
// Notify the requests on this NAI that the network is now lingered.
private void notifyNetworkLosing(@NonNull final NetworkAgentInfo nai, final long now) {
final int lingerTime = (int) (nai.getLingerExpiry() - now);
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime);
}
/** /**
* Notify of the blocked state apps with a registered callback matching a given NAI. * Notify of the blocked state apps with a registered callback matching a given NAI.
* *