Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 151384dd authored by Jimmy Chen's avatar Jimmy Chen
Browse files

p2p: revise tethering handler for shared group interface support

When leaving a group, all information are erased and no group interface
is passed to tethering service.
For separate group interface, tethering could be stopped
on p2p group interface removed. For shared group interface,
i.e. management interface and group interface share one
interface, ex. p2p0, tethering has no chance to be stopped since management
interface won't be removed after leaving a group.

Bug: 141382930
Test: atest FrameworksNetTests
Test: atest FrameworksWifiTests
Test: atest TetheringTests
Change-Id: Ib611018b67c76ff79c7e6658136721090feb145b
parent 57726b75
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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.
+32 −17
Original line number Diff line number Diff line
@@ -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");
@@ -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;

@@ -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);
            }
        }

@@ -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);
    }

+11 −1
Original line number Diff line number Diff line
@@ -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),
@@ -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;
    }
}
+7 −5
Original line number Diff line number Diff line
@@ -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);