Merge "Fix a race when removing from LegacyTypeTracker." into mnc-dev

This commit is contained in:
Lorenzo Colitti
2015-05-13 06:31:36 +00:00
committed by Android (Google) Code Review

View File

@@ -463,11 +463,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
} }
private void maybeLogBroadcast(NetworkAgentInfo nai, boolean connected, int type) { private void maybeLogBroadcast(NetworkAgentInfo nai, boolean connected, int type,
boolean isDefaultNetwork) {
if (DBG) { if (DBG) {
log("Sending " + (connected ? "connected" : "disconnected") + log("Sending " + (connected ? "connected" : "disconnected") +
" broadcast for type " + type + " " + nai.name() + " broadcast for type " + type + " " + nai.name() +
" isDefaultNetwork=" + isDefaultNetwork(nai)); " isDefaultNetwork=" + isDefaultNetwork);
} }
} }
@@ -487,43 +488,45 @@ public class ConnectivityService extends IConnectivityManager.Stub
list.add(nai); list.add(nai);
// Send a broadcast if this is the first network of its type or if it's the default. // Send a broadcast if this is the first network of its type or if it's the default.
if (list.size() == 1 || isDefaultNetwork(nai)) { final boolean isDefaultNetwork = isDefaultNetwork(nai);
maybeLogBroadcast(nai, true, type); if (list.size() == 1 || isDefaultNetwork) {
maybeLogBroadcast(nai, true, type, isDefaultNetwork);
sendLegacyNetworkBroadcast(nai, true, type); sendLegacyNetworkBroadcast(nai, true, type);
} }
} }
/** Removes the given network from the specified legacy type list. */ /** Removes the given network from the specified legacy type list. */
public void remove(int type, NetworkAgentInfo nai) { public void remove(int type, NetworkAgentInfo nai, boolean wasDefault) {
ArrayList<NetworkAgentInfo> list = mTypeLists[type]; ArrayList<NetworkAgentInfo> list = mTypeLists[type];
if (list == null || list.isEmpty()) { if (list == null || list.isEmpty()) {
return; return;
} }
boolean wasFirstNetwork = list.get(0).equals(nai); final boolean wasFirstNetwork = list.get(0).equals(nai);
if (!list.remove(nai)) { if (!list.remove(nai)) {
return; return;
} }
if (wasFirstNetwork || isDefaultNetwork(nai)) { if (wasFirstNetwork || wasDefault) {
maybeLogBroadcast(nai, false, type); maybeLogBroadcast(nai, false, type, wasDefault);
sendLegacyNetworkBroadcast(nai, false, type); sendLegacyNetworkBroadcast(nai, false, type);
} }
if (!list.isEmpty() && wasFirstNetwork) { if (!list.isEmpty() && wasFirstNetwork) {
if (DBG) log("Other network available for type " + type + if (DBG) log("Other network available for type " + type +
", sending connected broadcast"); ", sending connected broadcast");
maybeLogBroadcast(list.get(0), false, type); final NetworkAgentInfo replacement = list.get(0);
sendLegacyNetworkBroadcast(list.get(0), false, type); maybeLogBroadcast(replacement, false, type, isDefaultNetwork(replacement));
sendLegacyNetworkBroadcast(replacement, false, type);
} }
} }
/** Removes the given network from all legacy type lists. */ /** Removes the given network from all legacy type lists. */
public void remove(NetworkAgentInfo nai) { public void remove(NetworkAgentInfo nai, boolean wasDefault) {
if (VDBG) log("Removing agent " + nai); if (VDBG) log("Removing agent " + nai + " wasDefault=" + wasDefault);
for (int type = 0; type < mTypeLists.length; type++) { for (int type = 0; type < mTypeLists.length; type++) {
remove(type, nai); remove(type, nai, wasDefault);
} }
} }
@@ -2036,12 +2039,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
loge("Error connecting NetworkAgent"); loge("Error connecting NetworkAgent");
NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo); NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo);
if (nai != null) { if (nai != null) {
final boolean wasDefault = isDefaultNetwork(nai);
synchronized (mNetworkForNetId) { synchronized (mNetworkForNetId) {
mNetworkForNetId.remove(nai.network.netId); mNetworkForNetId.remove(nai.network.netId);
mNetIdInUse.delete(nai.network.netId); mNetIdInUse.delete(nai.network.netId);
} }
// Just in case. // Just in case.
mLegacyTypeTracker.remove(nai); mLegacyTypeTracker.remove(nai, wasDefault);
} }
} }
} }
@@ -2071,7 +2075,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
null, null); null, null);
} }
if (isDefaultNetwork(nai)) { final boolean wasDefault = isDefaultNetwork(nai);
if (wasDefault) {
mDefaultInetConditionPublished = 0; mDefaultInetConditionPublished = 0;
} }
notifyIfacesChanged(); notifyIfacesChanged();
@@ -2079,7 +2084,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED); nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
mNetworkAgentInfos.remove(msg.replyTo); mNetworkAgentInfos.remove(msg.replyTo);
updateClat(null, nai.linkProperties, nai); updateClat(null, nai.linkProperties, nai);
mLegacyTypeTracker.remove(nai);
synchronized (mNetworkForNetId) { synchronized (mNetworkForNetId) {
mNetworkForNetId.remove(nai.network.netId); mNetworkForNetId.remove(nai.network.netId);
mNetIdInUse.delete(nai.network.netId); mNetIdInUse.delete(nai.network.netId);
@@ -2118,6 +2122,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
notifyLockdownVpn(nai); notifyLockdownVpn(nai);
requestNetworkTransitionWakelock(nai.name()); requestNetworkTransitionWakelock(nai.name());
} }
mLegacyTypeTracker.remove(nai, wasDefault);
for (NetworkAgentInfo networkToActivate : toActivate) { for (NetworkAgentInfo networkToActivate : toActivate) {
unlinger(networkToActivate); unlinger(networkToActivate);
rematchNetworkAndRequests(networkToActivate, NascentState.NOT_JUST_VALIDATED, rematchNetworkAndRequests(networkToActivate, NascentState.NOT_JUST_VALIDATED,
@@ -2307,7 +2312,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
if (doRemove) { if (doRemove) {
mLegacyTypeTracker.remove(nri.request.legacyType, nai); mLegacyTypeTracker.remove(nri.request.legacyType, nai, false);
} }
} }
@@ -4190,7 +4195,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// the new one connected. // the new one connected.
if (oldDefaultNetwork != null) { if (oldDefaultNetwork != null) {
mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(), mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(),
oldDefaultNetwork); oldDefaultNetwork, true);
} }
mDefaultInetConditionPublished = newNetwork.everValidated ? 100 : 0; mDefaultInetConditionPublished = newNetwork.everValidated ? 100 : 0;
mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork); mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork);