From 0640cdd9fa94133e19c9cd18632338ef6908cd49 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Sat, 24 May 2014 02:25:55 +0900 Subject: [PATCH] Support disconnecting while trying to connect. Currently, once a NetworkAgent has decided to connect, there's no way to disconnect without first connecting and having ConnectivityService tear down the connection. This is suboptimal because it causes the transport to keep retrying even if it knows that it will not be able to connect. Instead, allow the transport to abort a connection request that's in progress, as long as the agent is not yet registered with ConnectivityService. Also add locking to evalScores. evalScores should already have been taking a lock, because it accesses member variables that are also accessed by the send*methods. Bug: 15295359 Change-Id: I913c341bdfc50be9c23b632399f53168e754c1c0 --- core/java/android/net/NetworkAgent.java | 46 ++++++++++++++++--------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java index c2b06a297f..1c18ba5640 100644 --- a/core/java/android/net/NetworkAgent.java +++ b/core/java/android/net/NetworkAgent.java @@ -257,31 +257,43 @@ public abstract class NetworkAgent extends Handler { } /** - * called to go through our list of requests and see if we're - * good enough to try connecting. + * Called to go through our list of requests and see if we're + * good enough to try connecting, or if we have gotten worse and + * need to disconnect. * - * Only does connects - we disconnect when requested via + * Once we are registered, does nothing: we disconnect when requested via * CMD_CHANNEL_DISCONNECTED, generated by either a loss of connection * between modules (bearer or ConnectivityService dies) or more commonly * when the NetworkInfo reports to ConnectivityService it is disconnected. */ private void evalScores() { - if (mConnectionRequested) { - if (VDBG) log("evalScores - already trying - size=" + mNetworkRequests.size()); - // already trying - return; - } - if (VDBG) log("evalScores!"); - for (int i=0; i < mNetworkRequests.size(); i++) { - int score = mNetworkRequests.valueAt(i).score; - if (VDBG) log(" checking request Min " + score + " vs my score " + mNetworkScore); - if (score < mNetworkScore) { - // have a request that has a lower scored network servicing it - // (or no network) than we could provide, so lets connect! - mConnectionRequested = true; - connect(); + synchronized(mLockObj) { + if (mRegistered) { + if (VDBG) log("evalScores - already connected - size=" + mNetworkRequests.size()); + // already trying return; } + if (VDBG) log("evalScores!"); + for (int i=0; i < mNetworkRequests.size(); i++) { + int score = mNetworkRequests.valueAt(i).score; + if (VDBG) log(" checking request Min " + score + " vs my score " + mNetworkScore); + if (score < mNetworkScore) { + // have a request that has a lower scored network servicing it + // (or no network) than we could provide, so let's connect! + mConnectionRequested = true; + connect(); + return; + } + } + // Our score is not high enough to satisfy any current request. + // This can happen if our score goes down after a connection is + // requested but before we actually connect. In this case, disconnect + // rather than continue trying - there's no point connecting if we know + // we'll just be torn down as soon as we do. + if (mConnectionRequested) { + mConnectionRequested = false; + disconnect(); + } } }