Merge "Fix listeners not getting called when AVD falls back on UI thread" into nyc-mr1-dev
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index e0d8373..927f8f9 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -1616,6 +1616,7 @@
if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
if (mNotifyList.indexOf(who) < 0) {
mNotifyList.add(who);
+ mIPv6TetheringCoordinator.addActiveDownstream(who);
}
transitionTo(mTetherModeAliveState);
break;
@@ -1623,6 +1624,7 @@
who = (TetherInterfaceStateMachine)message.obj;
if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
mNotifyList.remove(who);
+ mIPv6TetheringCoordinator.removeActiveDownstream(who);
break;
default:
retValue = false;
@@ -1661,17 +1663,19 @@
maybeLogMessage(this, message.what);
boolean retValue = true;
switch (message.what) {
- case CMD_TETHER_MODE_REQUESTED:
+ case CMD_TETHER_MODE_REQUESTED: {
TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj;
if (VDBG) Log.d(TAG, "Tether Mode requested by " + who);
if (mNotifyList.indexOf(who) < 0) {
mNotifyList.add(who);
+ mIPv6TetheringCoordinator.addActiveDownstream(who);
}
who.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_CONNECTION_CHANGED,
mCurrentUpstreamIface);
break;
- case CMD_TETHER_MODE_UNREQUESTED:
- who = (TetherInterfaceStateMachine)message.obj;
+ }
+ case CMD_TETHER_MODE_UNREQUESTED: {
+ TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj;
if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who);
if (mNotifyList.remove(who)) {
if (DBG) Log.d(TAG, "TetherModeAlive removing notifyee " + who);
@@ -1689,7 +1693,9 @@
} else {
Log.e(TAG, "TetherModeAliveState UNREQUESTED has unknown who: " + who);
}
+ mIPv6TetheringCoordinator.removeActiveDownstream(who);
break;
+ }
case CMD_UPSTREAM_CHANGED:
// need to try DUN immediately if Wifi goes down
mTryCell = true;
diff --git a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java
index e94b584..9173feb 100644
--- a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java
+++ b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java
@@ -29,6 +29,7 @@
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.ArrayList;
+import java.util.LinkedList;
/**
@@ -45,10 +46,28 @@
private static final boolean VDBG = false;
private final ArrayList<TetherInterfaceStateMachine> mNotifyList;
+ private final LinkedList<TetherInterfaceStateMachine> mActiveDownstreams;
private NetworkState mUpstreamNetworkState;
public IPv6TetheringCoordinator(ArrayList<TetherInterfaceStateMachine> notifyList) {
mNotifyList = notifyList;
+ mActiveDownstreams = new LinkedList<>();
+ }
+
+ public void addActiveDownstream(TetherInterfaceStateMachine downstream) {
+ if (mActiveDownstreams.indexOf(downstream) == -1) {
+ // Adding a new downstream appends it to the list. Adding a
+ // downstream a second time without first removing it has no effect.
+ mActiveDownstreams.offer(downstream);
+ updateIPv6TetheringInterfaces();
+ }
+ }
+
+ public void removeActiveDownstream(TetherInterfaceStateMachine downstream) {
+ stopIPv6TetheringOn(downstream);
+ if (mActiveDownstreams.remove(downstream)) {
+ updateIPv6TetheringInterfaces();
+ }
}
public void updateUpstreamNetworkState(NetworkState ns) {
@@ -72,8 +91,7 @@
private void stopIPv6TetheringOnAllInterfaces() {
for (TetherInterfaceStateMachine sm : mNotifyList) {
- sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE,
- 0, 0, null);
+ stopIPv6TetheringOn(sm);
}
}
@@ -98,28 +116,32 @@
private void updateIPv6TetheringInterfaces() {
for (TetherInterfaceStateMachine sm : mNotifyList) {
- final LinkProperties lp = getInterfaceIPv6LinkProperties(sm.interfaceType());
+ final LinkProperties lp = getInterfaceIPv6LinkProperties(sm);
sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, lp);
break;
}
}
- private LinkProperties getInterfaceIPv6LinkProperties(int interfaceType) {
+ private LinkProperties getInterfaceIPv6LinkProperties(TetherInterfaceStateMachine sm) {
if (mUpstreamNetworkState == null) return null;
+ if (sm.interfaceType() == ConnectivityManager.TETHERING_BLUETOOTH) {
+ // TODO: Figure out IPv6 support on PAN interfaces.
+ return null;
+ }
+
// NOTE: Here, in future, we would have policies to decide how to divvy
// up the available dedicated prefixes among downstream interfaces.
// At this time we have no such mechanism--we only support tethering
- // IPv6 toward Wi-Fi interfaces.
+ // IPv6 toward the oldest (first requested) active downstream.
- switch (interfaceType) {
- case ConnectivityManager.TETHERING_WIFI:
- final LinkProperties lp = getIPv6OnlyLinkProperties(
- mUpstreamNetworkState.linkProperties);
- if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) {
- return lp;
- }
- break;
+ final TetherInterfaceStateMachine currentActive = mActiveDownstreams.peek();
+ if (currentActive != null && currentActive == sm) {
+ final LinkProperties lp = getIPv6OnlyLinkProperties(
+ mUpstreamNetworkState.linkProperties);
+ if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) {
+ return lp;
+ }
}
return null;
@@ -250,4 +272,8 @@
ns.networkCapabilities,
ns.linkProperties);
}
+
+ private static void stopIPv6TetheringOn(TetherInterfaceStateMachine sm) {
+ sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, null);
+ }
}