diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 6cc738b763..752dce9187 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -31,7 +31,6 @@ import static android.net.ConnectivityManager.TYPE_PROXY; import static android.net.ConnectivityManager.getNetworkTypeName; import static android.net.ConnectivityManager.isNetworkTypeValid; import static android.net.ConnectivityServiceProtocol.NetworkFactoryProtocol; -import static android.net.ConnectivityServiceProtocol.NetworkMonitorProtocol; import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; @@ -131,6 +130,7 @@ import com.android.server.am.BatteryStatsService; import com.android.server.connectivity.DataConnectionStats; import com.android.server.connectivity.Nat464Xlat; import com.android.server.connectivity.NetworkAgentInfo; +import com.android.server.connectivity.NetworkMonitor; import com.android.server.connectivity.PacManager; import com.android.server.connectivity.Tethering; import com.android.server.connectivity.Vpn; @@ -2932,12 +2932,12 @@ public class ConnectivityService extends IConnectivityManager.Stub { updateNetworkInfo(nai, info); break; } - case NetworkMonitorProtocol.EVENT_NETWORK_VALIDATED: { + case NetworkMonitor.EVENT_NETWORK_VALIDATED: { NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj; handleConnectionValidated(nai); break; } - case NetworkMonitorProtocol.EVENT_NETWORK_LINGER_COMPLETE: { + case NetworkMonitor.EVENT_NETWORK_LINGER_COMPLETE: { NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj; handleLingerComplete(nai); break; @@ -3068,21 +3068,39 @@ public class ConnectivityService extends IConnectivityManager.Stub { loge("Exception removing network: " + e); } notifyNetworkCallbacks(nai, NetworkCallbacks.LOST); + nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED); mNetworkAgentInfos.remove(nai); // Since we've lost the network, go through all the requests that // it was satisfying and see if any other factory can satisfy them. + final ArrayList toActivate = new ArrayList(); for (int i = 0; i < nai.networkRequests.size(); i++) { NetworkRequest request = nai.networkRequests.valueAt(i); NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(request.requestId); if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) { mNetworkForRequestId.remove(request.requestId); - // TODO Check if any other live network will work sendUpdatedScoreToFactories(request, 0); + NetworkAgentInfo alternative = null; + for (Map.Entry entry : mNetworkAgentInfos.entrySet()) { + NetworkAgentInfo existing = (NetworkAgentInfo)entry.getValue(); + if (existing.networkInfo.isConnected() && + request.networkCapabilities.satisfiedByNetworkCapabilities( + existing.networkCapabilities) && + (alternative == null || + alternative.currentScore < existing.currentScore)) { + alternative = existing; + } + } + if (alternative != null && !toActivate.contains(alternative)) { + toActivate.add(alternative); + } } } if (nai.networkRequests.get(mDefaultRequest.requestId) != null) { removeDataActivityTracking(nai); } + for (NetworkAgentInfo networkToActivate : toActivate) { + networkToActivate.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED); + } } } @@ -5070,7 +5088,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), nextNetId(), new NetworkInfo(networkInfo), new LinkProperties(linkProperties), - new NetworkCapabilities(networkCapabilities), currentScore); + new NetworkCapabilities(networkCapabilities), currentScore, mContext, mTrackerHandler); mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai)); } @@ -5238,14 +5256,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { currentNetwork.networkRequests.remove(nr.requestId); currentNetwork.networkListens.add(nr); if (currentNetwork.networkRequests.size() == 0) { - // TODO tell current Network to go to linger state - - // fake the linger state: - Message message = Message.obtain(); - message.obj = currentNetwork; - message.what = NetworkMonitorProtocol.EVENT_NETWORK_LINGER_COMPLETE; - mTrackerHandler.sendMessage(message); - + currentNetwork.networkMonitor.sendMessage( + NetworkMonitor.CMD_NETWORK_LINGER); notifyNetworkCallbacks(currentNetwork, NetworkCallbacks.LOSING); } } @@ -5301,7 +5313,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { //BatteryStatsService.getService().noteNetworkInterfaceType(iface, netType); // } catch (RemoteException e) { } notifyNetworkCallbacks(newNetwork, NetworkCallbacks.AVAILABLE); - } else { + } else if (newNetwork.networkRequests.size() == 0) { if (VDBG) log("Validated network turns out to be unwanted. Tear it down."); newNetwork.asyncChannel.disconnect(); } @@ -5331,13 +5343,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { } updateLinkProperties(networkAgent, null); notifyNetworkCallbacks(networkAgent, NetworkCallbacks.PRECHECK); - // TODO - kick the network monitor - - // Fake things by sending self a NETWORK_VALIDATED msg - Message message = Message.obtain(); - message.obj = networkAgent; - message.what = NetworkMonitorProtocol.EVENT_NETWORK_VALIDATED; - mTrackerHandler.sendMessage(message); + networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED); } else if (state == NetworkInfo.State.DISCONNECTED || state == NetworkInfo.State.SUSPENDED) { networkAgent.asyncChannel.disconnect(); diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index 4747487705..0c568b73f9 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -16,15 +16,18 @@ package com.android.server.connectivity; +import android.content.Context; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkRequest; +import android.os.Handler; import android.os.Messenger; import android.util.SparseArray; import com.android.internal.util.AsyncChannel; +import com.android.server.connectivity.NetworkMonitor; import java.util.ArrayList; @@ -40,6 +43,8 @@ public class NetworkAgentInfo { public LinkProperties linkProperties; public NetworkCapabilities networkCapabilities; public int currentScore; + public final NetworkMonitor networkMonitor; + // The list of NetworkRequests being satisfied by this Network. public final SparseArray networkRequests = new SparseArray(); @@ -50,7 +55,8 @@ public class NetworkAgentInfo { public final AsyncChannel asyncChannel; public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, int netId, NetworkInfo info, - LinkProperties lp, NetworkCapabilities nc, int score) { + LinkProperties lp, NetworkCapabilities nc, int score, Context context, + Handler handler) { this.messenger = messenger; asyncChannel = ac; network = new Network(netId); @@ -58,7 +64,7 @@ public class NetworkAgentInfo { linkProperties = lp; networkCapabilities = nc; currentScore = score; - + networkMonitor = new NetworkMonitor(context, handler, this); } public String toString() {