Loading packages/Tethering/src/android/net/ip/IpServer.java +2 −1 Original line number Diff line number Diff line Loading @@ -441,7 +441,8 @@ public class IpServer extends StateMachine { } final Boolean setIfaceUp; if (mInterfaceType == TetheringManager.TETHERING_WIFI) { if (mInterfaceType == TetheringManager.TETHERING_WIFI || mInterfaceType == TetheringManager.TETHERING_WIFI_P2P) { // The WiFi stack has ownership of the interface up/down state. // It is unclear whether the Bluetooth or USB stacks will manage their own // state. Loading packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +32 −17 Original line number Diff line number Diff line Loading @@ -207,6 +207,7 @@ public class Tethering { private Network mTetherUpstream; private TetherStatesParcel mTetherStatesParcel; private boolean mDataSaverEnabled = false; private String mWifiP2pTetherInterface = null; public Tethering(TetheringDependencies deps) { mLog.mark("Tethering.constructed"); Loading Loading @@ -852,6 +853,11 @@ public class Tethering { } } private boolean isGroupOwner(WifiP2pGroup group) { return group != null && group.isGroupOwner() && !TextUtils.isEmpty(group.getInterface()); } private void handleWifiP2pAction(Intent intent) { if (mConfig.isWifiP2pLegacyTetheringMode()) return; Loading @@ -864,24 +870,31 @@ public class Tethering { Log.d(TAG, "WifiP2pAction: P2pInfo: " + p2pInfo + " Group: " + group); } if (p2pInfo == null) return; // When a p2p group is disconnected, p2pInfo would be cleared. // group is still valid for detecting whether this device is group owner. if (group == null || !group.isGroupOwner() || TextUtils.isEmpty(group.getInterface())) return; synchronized (Tethering.this.mPublicSync) { // Enter below only if this device is Group Owner with a valid interface. if (p2pInfo.groupFormed) { TetherState tetherState = mTetherStates.get(group.getInterface()); if (tetherState == null || (tetherState.lastState != IpServer.STATE_TETHERED && tetherState.lastState != IpServer.STATE_LOCAL_ONLY)) { enableWifiIpServingLocked(group.getInterface(), IFACE_IP_MODE_LOCAL_ONLY); // if no group is formed, bring it down if needed. if (p2pInfo == null || !p2pInfo.groupFormed) { disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface); mWifiP2pTetherInterface = null; return; } } else { disableWifiP2pIpServingLocked(group.getInterface()); // If there is a group but the device is not the owner, bail out. if (!isGroupOwner(group)) return; // If already serving from the correct interface, nothing to do. if (group.getInterface().equals(mWifiP2pTetherInterface)) return; // If already serving from another interface, turn it down first. if (!TextUtils.isEmpty(mWifiP2pTetherInterface)) { mLog.w("P2P tethered interface " + mWifiP2pTetherInterface + "is different from current interface " + group.getInterface() + ", re-tether it"); disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface); } // Finally bring up serving on the new interface mWifiP2pTetherInterface = group.getInterface(); enableWifiIpServingLocked(mWifiP2pTetherInterface, IFACE_IP_MODE_LOCAL_ONLY); } } Loading Loading @@ -979,7 +992,9 @@ public class Tethering { disableWifiIpServingLockedCommon(TETHERING_WIFI, ifname, apState); } private void disableWifiP2pIpServingLocked(String ifname) { private void disableWifiP2pIpServingLockedIfNeeded(String ifname) { if (TextUtils.isEmpty(ifname)) return; disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* dummy */ 0); } Loading packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java +11 −1 Original line number Diff line number Diff line Loading @@ -273,7 +273,7 @@ public class IpServerTest { dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY); InOrder inOrder = inOrder(mCallback, mNetd); inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP))); IFACE_NAME.equals(cfg.ifName) && assertNotContainsFlag(cfg.flags, IF_STATE_UP))); inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME); inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME); inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME), Loading Loading @@ -547,4 +547,14 @@ public class IpServerTest { fail("Missing flag: " + match); return false; } private boolean assertNotContainsFlag(String[] flags, String match) { for (String flag : flags) { if (flag.equals(match)) { fail("Unexpected flag: " + match); return false; } } return true; } } packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java +7 −5 Original line number Diff line number Diff line Loading @@ -493,13 +493,15 @@ public class TetheringTest { private void sendWifiP2pConnectionChanged( boolean isGroupFormed, boolean isGroupOwner, String ifname) { WifiP2pGroup group = null; WifiP2pInfo p2pInfo = new WifiP2pInfo(); p2pInfo.groupFormed = isGroupFormed; if (isGroupFormed) { p2pInfo.isGroupOwner = isGroupOwner; WifiP2pGroup group = mock(WifiP2pGroup.class); group = mock(WifiP2pGroup.class); when(group.isGroupOwner()).thenReturn(isGroupOwner); when(group.getInterface()).thenReturn(ifname); } final Intent intent = mock(Intent.class); when(intent.getAction()).thenReturn(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); Loading Loading
packages/Tethering/src/android/net/ip/IpServer.java +2 −1 Original line number Diff line number Diff line Loading @@ -441,7 +441,8 @@ public class IpServer extends StateMachine { } final Boolean setIfaceUp; if (mInterfaceType == TetheringManager.TETHERING_WIFI) { if (mInterfaceType == TetheringManager.TETHERING_WIFI || mInterfaceType == TetheringManager.TETHERING_WIFI_P2P) { // The WiFi stack has ownership of the interface up/down state. // It is unclear whether the Bluetooth or USB stacks will manage their own // state. Loading
packages/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +32 −17 Original line number Diff line number Diff line Loading @@ -207,6 +207,7 @@ public class Tethering { private Network mTetherUpstream; private TetherStatesParcel mTetherStatesParcel; private boolean mDataSaverEnabled = false; private String mWifiP2pTetherInterface = null; public Tethering(TetheringDependencies deps) { mLog.mark("Tethering.constructed"); Loading Loading @@ -852,6 +853,11 @@ public class Tethering { } } private boolean isGroupOwner(WifiP2pGroup group) { return group != null && group.isGroupOwner() && !TextUtils.isEmpty(group.getInterface()); } private void handleWifiP2pAction(Intent intent) { if (mConfig.isWifiP2pLegacyTetheringMode()) return; Loading @@ -864,24 +870,31 @@ public class Tethering { Log.d(TAG, "WifiP2pAction: P2pInfo: " + p2pInfo + " Group: " + group); } if (p2pInfo == null) return; // When a p2p group is disconnected, p2pInfo would be cleared. // group is still valid for detecting whether this device is group owner. if (group == null || !group.isGroupOwner() || TextUtils.isEmpty(group.getInterface())) return; synchronized (Tethering.this.mPublicSync) { // Enter below only if this device is Group Owner with a valid interface. if (p2pInfo.groupFormed) { TetherState tetherState = mTetherStates.get(group.getInterface()); if (tetherState == null || (tetherState.lastState != IpServer.STATE_TETHERED && tetherState.lastState != IpServer.STATE_LOCAL_ONLY)) { enableWifiIpServingLocked(group.getInterface(), IFACE_IP_MODE_LOCAL_ONLY); // if no group is formed, bring it down if needed. if (p2pInfo == null || !p2pInfo.groupFormed) { disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface); mWifiP2pTetherInterface = null; return; } } else { disableWifiP2pIpServingLocked(group.getInterface()); // If there is a group but the device is not the owner, bail out. if (!isGroupOwner(group)) return; // If already serving from the correct interface, nothing to do. if (group.getInterface().equals(mWifiP2pTetherInterface)) return; // If already serving from another interface, turn it down first. if (!TextUtils.isEmpty(mWifiP2pTetherInterface)) { mLog.w("P2P tethered interface " + mWifiP2pTetherInterface + "is different from current interface " + group.getInterface() + ", re-tether it"); disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface); } // Finally bring up serving on the new interface mWifiP2pTetherInterface = group.getInterface(); enableWifiIpServingLocked(mWifiP2pTetherInterface, IFACE_IP_MODE_LOCAL_ONLY); } } Loading Loading @@ -979,7 +992,9 @@ public class Tethering { disableWifiIpServingLockedCommon(TETHERING_WIFI, ifname, apState); } private void disableWifiP2pIpServingLocked(String ifname) { private void disableWifiP2pIpServingLockedIfNeeded(String ifname) { if (TextUtils.isEmpty(ifname)) return; disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* dummy */ 0); } Loading
packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java +11 −1 Original line number Diff line number Diff line Loading @@ -273,7 +273,7 @@ public class IpServerTest { dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_LOCAL_ONLY); InOrder inOrder = inOrder(mCallback, mNetd); inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> IFACE_NAME.equals(cfg.ifName) && assertContainsFlag(cfg.flags, IF_STATE_UP))); IFACE_NAME.equals(cfg.ifName) && assertNotContainsFlag(cfg.flags, IF_STATE_UP))); inOrder.verify(mNetd).tetherInterfaceAdd(IFACE_NAME); inOrder.verify(mNetd).networkAddInterface(INetd.LOCAL_NET_ID, IFACE_NAME); inOrder.verify(mNetd, times(2)).networkAddRoute(eq(INetd.LOCAL_NET_ID), eq(IFACE_NAME), Loading Loading @@ -547,4 +547,14 @@ public class IpServerTest { fail("Missing flag: " + match); return false; } private boolean assertNotContainsFlag(String[] flags, String match) { for (String flag : flags) { if (flag.equals(match)) { fail("Unexpected flag: " + match); return false; } } return true; } }
packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java +7 −5 Original line number Diff line number Diff line Loading @@ -493,13 +493,15 @@ public class TetheringTest { private void sendWifiP2pConnectionChanged( boolean isGroupFormed, boolean isGroupOwner, String ifname) { WifiP2pGroup group = null; WifiP2pInfo p2pInfo = new WifiP2pInfo(); p2pInfo.groupFormed = isGroupFormed; if (isGroupFormed) { p2pInfo.isGroupOwner = isGroupOwner; WifiP2pGroup group = mock(WifiP2pGroup.class); group = mock(WifiP2pGroup.class); when(group.isGroupOwner()).thenReturn(isGroupOwner); when(group.getInterface()).thenReturn(ifname); } final Intent intent = mock(Intent.class); when(intent.getAction()).thenReturn(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); Loading