Merge "[VCN09] Rename linger timer"
This commit is contained in:
@@ -2726,9 +2726,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
pw.println(nai.requestAt(i).toString());
|
pw.println(nai.requestAt(i).toString());
|
||||||
}
|
}
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
pw.println("Lingered:");
|
pw.println("Inactivity Timers:");
|
||||||
pw.increaseIndent();
|
pw.increaseIndent();
|
||||||
nai.dumpLingerTimers(pw);
|
nai.dumpInactivityTimers(pw);
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
}
|
}
|
||||||
@@ -3323,27 +3323,27 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the linger state from the network requests inside the NAI.
|
* Updates the inactivity state from the network requests inside the NAI.
|
||||||
* @param nai the agent info to update
|
* @param nai the agent info to update
|
||||||
* @param now the timestamp of the event causing this update
|
* @param now the timestamp of the event causing this update
|
||||||
* @return whether the network was lingered as a result of this update
|
* @return whether the network was inactive as a result of this update
|
||||||
*/
|
*/
|
||||||
private boolean updateLingerState(@NonNull final NetworkAgentInfo nai, final long now) {
|
private boolean updateInactivityState(@NonNull final NetworkAgentInfo nai, final long now) {
|
||||||
// 1. Update the linger timer. If it's changed, reschedule or cancel the alarm.
|
// 1. Update the inactivity 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 inactive and there are now requests, unset inactive.
|
||||||
// 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
|
||||||
// one lingered request, start lingering.
|
// one lingered request, set inactive.
|
||||||
nai.updateLingerTimer();
|
nai.updateInactivityTimer();
|
||||||
if (nai.isLingering() && nai.numForegroundNetworkRequests() > 0) {
|
if (nai.isLingering() && nai.numForegroundNetworkRequests() > 0) {
|
||||||
if (DBG) log("Unlingering " + nai.toShortString());
|
if (DBG) log("Unsetting inactive " + nai.toShortString());
|
||||||
nai.unlinger();
|
nai.unsetInactive();
|
||||||
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.getInactivityExpiry() > 0) {
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
final int lingerTime = (int) (nai.getLingerExpiry() - now);
|
final int lingerTime = (int) (nai.getInactivityExpiry() - now);
|
||||||
log("Lingering " + nai.toShortString() + " for " + lingerTime + "ms");
|
log("Setting inactive " + nai.toShortString() + " for " + lingerTime + "ms");
|
||||||
}
|
}
|
||||||
nai.linger();
|
nai.setInactive();
|
||||||
logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER);
|
logNetworkEvent(nai, NetworkEvent.NETWORK_LINGER);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -3481,7 +3481,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nai.clearLingerState();
|
nai.clearInactivityState();
|
||||||
// TODO: mLegacyTypeTracker.remove seems redundant given there's a full rematch right after.
|
// TODO: mLegacyTypeTracker.remove seems redundant given there's a full rematch right after.
|
||||||
// Currently, deleting it breaks tests that check for the default network disconnecting.
|
// Currently, deleting it breaks tests that check for the default network disconnecting.
|
||||||
// Find out why, fix the rematch code, and delete this.
|
// Find out why, fix the rematch code, and delete this.
|
||||||
@@ -3823,7 +3823,7 @@ 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.
|
||||||
final long now = SystemClock.elapsedRealtime();
|
final long now = SystemClock.elapsedRealtime();
|
||||||
if (updateLingerState(nai, now)) {
|
if (updateInactivityState(nai, now)) {
|
||||||
notifyNetworkLosing(nai, now);
|
notifyNetworkLosing(nai, now);
|
||||||
}
|
}
|
||||||
if (unneeded(nai, UnneededFor.TEARDOWN)) {
|
if (unneeded(nai, UnneededFor.TEARDOWN)) {
|
||||||
@@ -7238,7 +7238,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
|
|
||||||
// If we get here it means that the last linger timeout for this network expired. So there
|
// If we get here it means that the last linger timeout for this network expired. So there
|
||||||
// must be no other active linger timers, and we must stop lingering.
|
// must be no other active linger timers, and we must stop lingering.
|
||||||
oldNetwork.clearLingerState();
|
oldNetwork.clearInactivityState();
|
||||||
|
|
||||||
if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) {
|
if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) {
|
||||||
// Tear the network down.
|
// Tear the network down.
|
||||||
@@ -7651,7 +7651,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// 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.
|
||||||
if (updateLingerState(nai, now)) {
|
if (updateInactivityState(nai, now)) {
|
||||||
lingeredNetworks.add(nai);
|
lingeredNetworks.add(nai);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7678,7 +7678,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// Tear down all unneeded networks.
|
// Tear down all unneeded networks.
|
||||||
for (NetworkAgentInfo nai : mNetworkAgentInfos) {
|
for (NetworkAgentInfo nai : mNetworkAgentInfos) {
|
||||||
if (unneeded(nai, UnneededFor.TEARDOWN)) {
|
if (unneeded(nai, UnneededFor.TEARDOWN)) {
|
||||||
if (nai.getLingerExpiry() > 0) {
|
if (nai.getInactivityExpiry() > 0) {
|
||||||
// This network has active linger timers and no requests, but is not
|
// This network has active linger timers and no requests, but is not
|
||||||
// lingering. Linger it.
|
// lingering. Linger it.
|
||||||
//
|
//
|
||||||
@@ -7686,7 +7686,7 @@ 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.
|
||||||
if (updateLingerState(nai, now)) {
|
if (updateInactivityState(nai, now)) {
|
||||||
notifyNetworkLosing(nai, now);
|
notifyNetworkLosing(nai, now);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -7963,7 +7963,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
|
|
||||||
// Notify the requests on this NAI that the network is now lingered.
|
// Notify the requests on this NAI that the network is now lingered.
|
||||||
private void notifyNetworkLosing(@NonNull final NetworkAgentInfo nai, final long now) {
|
private void notifyNetworkLosing(@NonNull final NetworkAgentInfo nai, final long now) {
|
||||||
final int lingerTime = (int) (nai.getLingerExpiry() - now);
|
final int lingerTime = (int) (nai.getInactivityExpiry() - now);
|
||||||
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime);
|
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -210,23 +210,23 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
|||||||
// network is taken down. This usually only happens to the default network. Lingering ends with
|
// network is taken down. This usually only happens to the default network. Lingering ends with
|
||||||
// either the linger timeout expiring and the network being taken down, or the network
|
// either the linger timeout expiring and the network being taken down, or the network
|
||||||
// satisfying a request again.
|
// satisfying a request again.
|
||||||
public static class LingerTimer implements Comparable<LingerTimer> {
|
public static class InactivityTimer implements Comparable<InactivityTimer> {
|
||||||
public final int requestId;
|
public final int requestId;
|
||||||
public final long expiryMs;
|
public final long expiryMs;
|
||||||
|
|
||||||
public LingerTimer(int requestId, long expiryMs) {
|
public InactivityTimer(int requestId, long expiryMs) {
|
||||||
this.requestId = requestId;
|
this.requestId = requestId;
|
||||||
this.expiryMs = expiryMs;
|
this.expiryMs = expiryMs;
|
||||||
}
|
}
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (!(o instanceof LingerTimer)) return false;
|
if (!(o instanceof InactivityTimer)) return false;
|
||||||
LingerTimer other = (LingerTimer) o;
|
InactivityTimer other = (InactivityTimer) o;
|
||||||
return (requestId == other.requestId) && (expiryMs == other.expiryMs);
|
return (requestId == other.requestId) && (expiryMs == other.expiryMs);
|
||||||
}
|
}
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(requestId, expiryMs);
|
return Objects.hash(requestId, expiryMs);
|
||||||
}
|
}
|
||||||
public int compareTo(LingerTimer other) {
|
public int compareTo(InactivityTimer other) {
|
||||||
return (expiryMs != other.expiryMs) ?
|
return (expiryMs != other.expiryMs) ?
|
||||||
Long.compare(expiryMs, other.expiryMs) :
|
Long.compare(expiryMs, other.expiryMs) :
|
||||||
Integer.compare(requestId, other.requestId);
|
Integer.compare(requestId, other.requestId);
|
||||||
@@ -269,30 +269,31 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
|||||||
*/
|
*/
|
||||||
public static final int ARG_AGENT_SUCCESS = 1;
|
public static final int ARG_AGENT_SUCCESS = 1;
|
||||||
|
|
||||||
// All linger timers for this network, sorted by expiry time. A linger timer is added whenever
|
// All inactivity timers for this network, sorted by expiry time. A timer is added whenever
|
||||||
// a request is moved to a network with a better score, regardless of whether the network is or
|
// a request is moved to a network with a better score, regardless of whether the network is or
|
||||||
// was lingering or not.
|
// was lingering or not.
|
||||||
// TODO: determine if we can replace this with a smaller or unsorted data structure. (e.g.,
|
// TODO: determine if we can replace this with a smaller or unsorted data structure. (e.g.,
|
||||||
// SparseLongArray) combined with the timestamp of when the last timer is scheduled to fire.
|
// SparseLongArray) combined with the timestamp of when the last timer is scheduled to fire.
|
||||||
private final SortedSet<LingerTimer> mLingerTimers = new TreeSet<>();
|
private final SortedSet<InactivityTimer> mInactivityTimers = new TreeSet<>();
|
||||||
|
|
||||||
// For fast lookups. Indexes into mLingerTimers by request ID.
|
// For fast lookups. Indexes into mInactivityTimers by request ID.
|
||||||
private final SparseArray<LingerTimer> mLingerTimerForRequest = new SparseArray<>();
|
private final SparseArray<InactivityTimer> mInactivityTimerForRequest = new SparseArray<>();
|
||||||
|
|
||||||
// Linger expiry timer. Armed whenever mLingerTimers is non-empty, regardless of whether the
|
// Inactivity expiry timer. Armed whenever mInactivityTimers is non-empty, regardless of
|
||||||
// network is lingering or not. Always set to the expiry of the LingerTimer that expires last.
|
// whether the network is inactive or not. Always set to the expiry of the mInactivityTimers
|
||||||
// When the timer fires, all linger state is cleared, and if the network has no requests, it is
|
// that expires last. When the timer fires, all inactivity state is cleared, and if the network
|
||||||
// torn down.
|
// has no requests, it is torn down.
|
||||||
private WakeupMessage mLingerMessage;
|
private WakeupMessage mInactivityMessage;
|
||||||
|
|
||||||
// Linger expiry. Holds the expiry time of the linger timer, or 0 if the timer is not armed.
|
// Inactivity expiry. Holds the expiry time of the inactivity timer, or 0 if the timer is not
|
||||||
private long mLingerExpiryMs;
|
// armed.
|
||||||
|
private long mInactivityExpiryMs;
|
||||||
|
|
||||||
// Whether the network is lingering or not. Must be maintained separately from the above because
|
// Whether the network is inactive or not. Must be maintained separately from the above because
|
||||||
// it depends on the state of other networks and requests, which only ConnectivityService knows.
|
// it depends on the state of other networks and requests, which only ConnectivityService knows.
|
||||||
// (Example: we don't linger a network if it would become the best for a NetworkRequest if it
|
// (Example: we don't linger a network if it would become the best for a NetworkRequest if it
|
||||||
// validated).
|
// validated).
|
||||||
private boolean mLingering;
|
private boolean mInactive;
|
||||||
|
|
||||||
// This represents the quality of the network with no clear scale.
|
// This represents the quality of the network with no clear scale.
|
||||||
private int mScore;
|
private int mScore;
|
||||||
@@ -898,17 +899,17 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
|||||||
* ConnectivityService when the request is moved to another network with a higher score.
|
* ConnectivityService when the request is moved to another network with a higher score.
|
||||||
*/
|
*/
|
||||||
public void lingerRequest(int requestId, long now, long duration) {
|
public void lingerRequest(int requestId, long now, long duration) {
|
||||||
if (mLingerTimerForRequest.get(requestId) != null) {
|
if (mInactivityTimerForRequest.get(requestId) != null) {
|
||||||
// Cannot happen. Once a request is lingering on a particular network, we cannot
|
// Cannot happen. Once a request is lingering on a particular network, we cannot
|
||||||
// re-linger it unless that network becomes the best for that request again, in which
|
// re-linger it unless that network becomes the best for that request again, in which
|
||||||
// case we should have unlingered it.
|
// case we should have unlingered it.
|
||||||
Log.wtf(TAG, toShortString() + ": request " + requestId + " already lingered");
|
Log.wtf(TAG, toShortString() + ": request " + requestId + " already lingered");
|
||||||
}
|
}
|
||||||
final long expiryMs = now + duration;
|
final long expiryMs = now + duration;
|
||||||
LingerTimer timer = new LingerTimer(requestId, expiryMs);
|
InactivityTimer timer = new InactivityTimer(requestId, expiryMs);
|
||||||
if (VDBG) Log.d(TAG, "Adding LingerTimer " + timer + " to " + toShortString());
|
if (VDBG) Log.d(TAG, "Adding InactivityTimer " + timer + " to " + toShortString());
|
||||||
mLingerTimers.add(timer);
|
mInactivityTimers.add(timer);
|
||||||
mLingerTimerForRequest.put(requestId, timer);
|
mInactivityTimerForRequest.put(requestId, timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -916,23 +917,25 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
|||||||
* Returns true if the given requestId was lingering on this network, false otherwise.
|
* Returns true if the given requestId was lingering on this network, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean unlingerRequest(int requestId) {
|
public boolean unlingerRequest(int requestId) {
|
||||||
LingerTimer timer = mLingerTimerForRequest.get(requestId);
|
InactivityTimer timer = mInactivityTimerForRequest.get(requestId);
|
||||||
if (timer != null) {
|
if (timer != null) {
|
||||||
if (VDBG) Log.d(TAG, "Removing LingerTimer " + timer + " from " + toShortString());
|
if (VDBG) {
|
||||||
mLingerTimers.remove(timer);
|
Log.d(TAG, "Removing InactivityTimer " + timer + " from " + toShortString());
|
||||||
mLingerTimerForRequest.remove(requestId);
|
}
|
||||||
|
mInactivityTimers.remove(timer);
|
||||||
|
mInactivityTimerForRequest.remove(requestId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLingerExpiry() {
|
public long getInactivityExpiry() {
|
||||||
return mLingerExpiryMs;
|
return mInactivityExpiryMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateLingerTimer() {
|
public void updateInactivityTimer() {
|
||||||
long newExpiry = mLingerTimers.isEmpty() ? 0 : mLingerTimers.last().expiryMs;
|
long newExpiry = mInactivityTimers.isEmpty() ? 0 : mInactivityTimers.last().expiryMs;
|
||||||
if (newExpiry == mLingerExpiryMs) return;
|
if (newExpiry == mInactivityExpiryMs) return;
|
||||||
|
|
||||||
// Even if we're going to reschedule the timer, cancel it first. This is because the
|
// Even if we're going to reschedule the timer, cancel it first. This is because the
|
||||||
// semantics of WakeupMessage guarantee that if cancel is called then the alarm will
|
// semantics of WakeupMessage guarantee that if cancel is called then the alarm will
|
||||||
@@ -940,49 +943,52 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
|
|||||||
// WakeupMessage makes no such guarantees about rescheduling a message, so if mLingerMessage
|
// WakeupMessage makes no such guarantees about rescheduling a message, so if mLingerMessage
|
||||||
// has already been dispatched, rescheduling to some time in the future won't stop it
|
// has already been dispatched, rescheduling to some time in the future won't stop it
|
||||||
// from calling its callback immediately.
|
// from calling its callback immediately.
|
||||||
if (mLingerMessage != null) {
|
if (mInactivityMessage != null) {
|
||||||
mLingerMessage.cancel();
|
mInactivityMessage.cancel();
|
||||||
mLingerMessage = null;
|
mInactivityMessage = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newExpiry > 0) {
|
if (newExpiry > 0) {
|
||||||
mLingerMessage = new WakeupMessage(
|
mInactivityMessage = new WakeupMessage(
|
||||||
mContext, mHandler,
|
mContext, mHandler,
|
||||||
"NETWORK_LINGER_COMPLETE." + network.getNetId() /* cmdName */,
|
"NETWORK_LINGER_COMPLETE." + network.getNetId() /* cmdName */,
|
||||||
EVENT_NETWORK_LINGER_COMPLETE /* cmd */,
|
EVENT_NETWORK_LINGER_COMPLETE /* cmd */,
|
||||||
0 /* arg1 (unused) */, 0 /* arg2 (unused) */,
|
0 /* arg1 (unused) */, 0 /* arg2 (unused) */,
|
||||||
this /* obj (NetworkAgentInfo) */);
|
this /* obj (NetworkAgentInfo) */);
|
||||||
mLingerMessage.schedule(newExpiry);
|
mInactivityMessage.schedule(newExpiry);
|
||||||
}
|
}
|
||||||
|
|
||||||
mLingerExpiryMs = newExpiry;
|
mInactivityExpiryMs = newExpiry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void linger() {
|
public void setInactive() {
|
||||||
mLingering = true;
|
mInactive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unlinger() {
|
public void unsetInactive() {
|
||||||
mLingering = false;
|
mInactive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLingering() {
|
public boolean isLingering() {
|
||||||
return mLingering;
|
return mInactive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearLingerState() {
|
public void clearInactivityState() {
|
||||||
if (mLingerMessage != null) {
|
if (mInactivityMessage != null) {
|
||||||
mLingerMessage.cancel();
|
mInactivityMessage.cancel();
|
||||||
mLingerMessage = null;
|
mInactivityMessage = null;
|
||||||
}
|
}
|
||||||
mLingerTimers.clear();
|
mInactivityTimers.clear();
|
||||||
mLingerTimerForRequest.clear();
|
mInactivityTimerForRequest.clear();
|
||||||
updateLingerTimer(); // Sets mLingerExpiryMs, cancels and nulls out mLingerMessage.
|
// Sets mInactivityExpiryMs, cancels and nulls out mInactivityMessage.
|
||||||
mLingering = false;
|
updateInactivityTimer();
|
||||||
|
mInactive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dumpLingerTimers(PrintWriter pw) {
|
public void dumpInactivityTimers(PrintWriter pw) {
|
||||||
for (LingerTimer timer : mLingerTimers) { pw.println(timer); }
|
for (InactivityTimer timer : mInactivityTimers) {
|
||||||
|
pw.println(timer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user