Loading services/core/java/com/android/server/connectivity/Tethering.java +9 −3 Original line number Diff line number Diff line Loading @@ -1616,6 +1616,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering if (VDBG) Log.d(TAG, "Tether Mode requested by " + who); if (mNotifyList.indexOf(who) < 0) { mNotifyList.add(who); mIPv6TetheringCoordinator.addActiveDownstream(who); } transitionTo(mTetherModeAliveState); break; Loading @@ -1623,6 +1624,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering who = (TetherInterfaceStateMachine)message.obj; if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who); mNotifyList.remove(who); mIPv6TetheringCoordinator.removeActiveDownstream(who); break; default: retValue = false; Loading Loading @@ -1661,17 +1663,19 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering 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); Loading @@ -1689,7 +1693,9 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering } 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; Loading services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java +40 −14 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.util.Log; import java.net.Inet6Address; import java.net.InetAddress; import java.util.ArrayList; import java.util.LinkedList; /** Loading @@ -45,10 +46,28 @@ public class IPv6TetheringCoordinator { 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) { Loading @@ -72,8 +91,7 @@ public class IPv6TetheringCoordinator { private void stopIPv6TetheringOnAllInterfaces() { for (TetherInterfaceStateMachine sm : mNotifyList) { sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, null); stopIPv6TetheringOn(sm); } } Loading @@ -98,28 +116,32 @@ public class IPv6TetheringCoordinator { 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 TetherInterfaceStateMachine currentActive = mActiveDownstreams.peek(); if (currentActive != null && currentActive == sm) { final LinkProperties lp = getIPv6OnlyLinkProperties( mUpstreamNetworkState.linkProperties); if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) { return lp; } break; } return null; Loading Loading @@ -250,4 +272,8 @@ public class IPv6TetheringCoordinator { ns.networkCapabilities, ns.linkProperties); } private static void stopIPv6TetheringOn(TetherInterfaceStateMachine sm) { sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, null); } } Loading
services/core/java/com/android/server/connectivity/Tethering.java +9 −3 Original line number Diff line number Diff line Loading @@ -1616,6 +1616,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering if (VDBG) Log.d(TAG, "Tether Mode requested by " + who); if (mNotifyList.indexOf(who) < 0) { mNotifyList.add(who); mIPv6TetheringCoordinator.addActiveDownstream(who); } transitionTo(mTetherModeAliveState); break; Loading @@ -1623,6 +1624,7 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering who = (TetherInterfaceStateMachine)message.obj; if (VDBG) Log.d(TAG, "Tether Mode unrequested by " + who); mNotifyList.remove(who); mIPv6TetheringCoordinator.removeActiveDownstream(who); break; default: retValue = false; Loading Loading @@ -1661,17 +1663,19 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering 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); Loading @@ -1689,7 +1693,9 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering } 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; Loading
services/core/java/com/android/server/connectivity/tethering/IPv6TetheringCoordinator.java +40 −14 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.util.Log; import java.net.Inet6Address; import java.net.InetAddress; import java.util.ArrayList; import java.util.LinkedList; /** Loading @@ -45,10 +46,28 @@ public class IPv6TetheringCoordinator { 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) { Loading @@ -72,8 +91,7 @@ public class IPv6TetheringCoordinator { private void stopIPv6TetheringOnAllInterfaces() { for (TetherInterfaceStateMachine sm : mNotifyList) { sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, null); stopIPv6TetheringOn(sm); } } Loading @@ -98,28 +116,32 @@ public class IPv6TetheringCoordinator { 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 TetherInterfaceStateMachine currentActive = mActiveDownstreams.peek(); if (currentActive != null && currentActive == sm) { final LinkProperties lp = getIPv6OnlyLinkProperties( mUpstreamNetworkState.linkProperties); if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) { return lp; } break; } return null; Loading Loading @@ -250,4 +272,8 @@ public class IPv6TetheringCoordinator { ns.networkCapabilities, ns.linkProperties); } private static void stopIPv6TetheringOn(TetherInterfaceStateMachine sm) { sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, null); } }