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

Commit bcd86d0c authored by Jimmy Chen's avatar Jimmy Chen
Browse files

p2p: mirgrate p2p into tethering modes

Bug: 137602441
Bug: 139783330
Test: atest FrameworksNetTests
Test: atest FrameworksWifiTests
Test: CtsVerifier - Wi-Fi Direct
Test: Enable hotspot when P2P GO is running
      * P2P GO is terminated
      * hotspot is running
Test: Enable P2P GO when hotspot is running
      * hotspot is intact
      * P2P GO could not be launched
Test: Verify P2P functions with legacy WifiP2pService

Change-Id: Icb2e2b106ae52b19af29b7a1ebc55d3cdf80db9c
parent df2293f6
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -472,6 +472,14 @@ public class ConnectivityManager {
    @SystemApi
    public static final int TETHERING_BLUETOOTH = 2;

    /**
     * Wifi P2p tethering type.
     * Wifi P2p tethering is set through events automatically, and don't
     * need to start from #startTethering(int, boolean, OnStartTetheringCallback).
     * @hide
     */
    public static final int TETHERING_WIFI_P2P = 3;

    /**
     * Extra used for communicating with the TetherService. Includes the type of tethering to
     * enable if any.
+6 −0
Original line number Diff line number Diff line
@@ -375,6 +375,12 @@
    <string-array translatable="false" name="config_tether_wifi_regexs">
    </string-array>

    <!-- List of regexpressions describing the interface (if any) that represent tetherable
         Wifi P2P interfaces.  If the device doesn't want to support tethering over Wifi P2p this
         should be empty.  An example would be "p2p-p2p.*" -->
    <string-array translatable="false" name="config_tether_wifi_p2p_regexs">
    </string-array>

    <!-- List of regexpressions describing the interface (if any) that represent tetherable
         WiMAX interfaces.  If the device doesn't want to support tethering over Wifi this
         should be empty.  An example would be "softap.*" -->
+1 −0
Original line number Diff line number Diff line
@@ -1850,6 +1850,7 @@
  <java-symbol type="bool" name="config_tether_upstream_automatic" />
  <java-symbol type="array" name="config_tether_usb_regexs" />
  <java-symbol type="array" name="config_tether_wifi_regexs" />
  <java-symbol type="array" name="config_tether_wifi_p2p_regexs" />
  <java-symbol type="array" name="config_usbHostBlacklist" />
  <java-symbol type="array" name="config_serialPorts" />
  <java-symbol type="array" name="radioAttributes" />
+64 −10
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static android.net.ConnectivityManager.TETHERING_BLUETOOTH;
import static android.net.ConnectivityManager.TETHERING_INVALID;
import static android.net.ConnectivityManager.TETHERING_USB;
import static android.net.ConnectivityManager.TETHERING_WIFI;
import static android.net.ConnectivityManager.TETHERING_WIFI_P2P;
import static android.net.ConnectivityManager.TETHER_ERROR_MASTER_ERROR;
import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
import static android.net.ConnectivityManager.TETHER_ERROR_SERVICE_UNAVAIL;
@@ -77,6 +78,9 @@ import android.net.util.PrefixUtils;
import android.net.util.SharedLog;
import android.net.util.VersionedBroadcastListener;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -290,6 +294,7 @@ public class Tethering extends BaseNetworkObserver {
        filter.addAction(CONNECTIVITY_ACTION);
        filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
        filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
        mContext.registerReceiver(mStateReceiver, filter, null, handler);

        filter = new IntentFilter();
@@ -354,6 +359,8 @@ public class Tethering extends BaseNetworkObserver {

        if (cfg.isWifi(iface)) {
            return TETHERING_WIFI;
        } else if (cfg.isWifiP2p(iface)) {
            return TETHERING_WIFI_P2P;
        } else if (cfg.isUsb(iface)) {
            return TETHERING_USB;
        } else if (cfg.isBluetooth(iface)) {
@@ -514,6 +521,7 @@ public class Tethering extends BaseNetworkObserver {

    public void untetherAll() {
        stopTethering(TETHERING_WIFI);
        stopTethering(TETHERING_WIFI_P2P);
        stopTethering(TETHERING_USB);
        stopTethering(TETHERING_BLUETOOTH);
    }
@@ -700,6 +708,8 @@ public class Tethering extends BaseNetworkObserver {
                handleConnectivityAction(intent);
            } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
                handleWifiApAction(intent);
            } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
                handleWifiP2pAction(intent);
            } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
                mLog.log("OBSERVED configuration changed");
                updateConfiguration();
@@ -776,6 +786,39 @@ public class Tethering extends BaseNetworkObserver {
                }
            }
        }

        private void handleWifiP2pAction(Intent intent) {
            if (mConfig.isWifiP2pLegacyTetheringMode()) return;

            final WifiP2pInfo p2pInfo =
                    (WifiP2pInfo) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
            final WifiP2pGroup group =
                    (WifiP2pGroup) intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);

            if (VDBG) {
                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);
                    }
                } else {
                    disableWifiP2pIpServingLocked(group.getInterface());
                }
            }
        }
    }

    @VisibleForTesting
@@ -810,14 +853,11 @@ public class Tethering extends BaseNetworkObserver {
        }
    }

    private void disableWifiIpServingLocked(String ifname, int apState) {
        mLog.log("Canceling WiFi tethering request - AP_STATE=" + apState);

        // Regardless of whether we requested this transition, the AP has gone
        // down.  Don't try to tether again unless we're requested to do so.
        // TODO: Remove this altogether, once Wi-Fi reliably gives us an
        // interface name with every broadcast.
        mWifiTetherRequested = false;
    private void disableWifiIpServingLockedCommon(int tetheringType, String ifname, int apState) {
        mLog.log("Canceling WiFi tethering request -"
                + " type=" + tetheringType
                + " interface=" + ifname
                + " state=" + apState);

        if (!TextUtils.isEmpty(ifname)) {
            final TetherState ts = mTetherStates.get(ifname);
@@ -829,7 +869,7 @@ public class Tethering extends BaseNetworkObserver {

        for (int i = 0; i < mTetherStates.size(); i++) {
            final IpServer ipServer = mTetherStates.valueAt(i).ipServer;
            if (ipServer.interfaceType() == TETHERING_WIFI) {
            if (ipServer.interfaceType() == tetheringType) {
                ipServer.unwanted();
                return;
            }
@@ -840,6 +880,20 @@ public class Tethering extends BaseNetworkObserver {
                                           : "specified interface: " + ifname));
    }

    private void disableWifiIpServingLocked(String ifname, int apState) {
        // Regardless of whether we requested this transition, the AP has gone
        // down.  Don't try to tether again unless we're requested to do so.
        // TODO: Remove this altogether, once Wi-Fi reliably gives us an
        // interface name with every broadcast.
        mWifiTetherRequested = false;

        disableWifiIpServingLockedCommon(TETHERING_WIFI, ifname, apState);
    }

    private void disableWifiP2pIpServingLocked(String ifname) {
        disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* dummy */ 0);
    }

    private void enableWifiIpServingLocked(String ifname, int wifiIpMode) {
        // Map wifiIpMode values to IpServer.Callback serving states, inferring
        // from mWifiTetherRequested as a final "best guess".
@@ -857,7 +911,7 @@ public class Tethering extends BaseNetworkObserver {
        }

        if (!TextUtils.isEmpty(ifname)) {
            maybeTrackNewInterfaceLocked(ifname, TETHERING_WIFI);
            maybeTrackNewInterfaceLocked(ifname);
            changeInterfaceState(ifname, ipServingMode);
        } else {
            mLog.e(String.format(
+14 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static com.android.internal.R.array.config_tether_bluetooth_regexs;
import static com.android.internal.R.array.config_tether_dhcp_range;
import static com.android.internal.R.array.config_tether_upstream_types;
import static com.android.internal.R.array.config_tether_usb_regexs;
import static com.android.internal.R.array.config_tether_wifi_p2p_regexs;
import static com.android.internal.R.array.config_tether_wifi_regexs;
import static com.android.internal.R.bool.config_tether_upstream_automatic;
import static com.android.internal.R.integer.config_mobile_hotspot_provision_check_period;
@@ -85,6 +86,7 @@ public class TetheringConfiguration {

    public final String[] tetherableUsbRegexs;
    public final String[] tetherableWifiRegexs;
    public final String[] tetherableWifiP2pRegexs;
    public final String[] tetherableBluetoothRegexs;
    public final boolean isDunRequired;
    public final boolean chooseUpstreamAutomatically;
@@ -110,6 +112,7 @@ public class TetheringConfiguration {
        // us an interface name. Careful consideration needs to be given to
        // implications for Settings and for provisioning checks.
        tetherableWifiRegexs = getResourceStringArray(res, config_tether_wifi_regexs);
        tetherableWifiP2pRegexs = getResourceStringArray(res, config_tether_wifi_p2p_regexs);
        tetherableBluetoothRegexs = getResourceStringArray(res, config_tether_bluetooth_regexs);

        isDunRequired = checkDunRequired(ctx, subId);
@@ -138,6 +141,15 @@ public class TetheringConfiguration {
        return matchesDownstreamRegexs(iface, tetherableWifiRegexs);
    }

    /** Check whether this interface is Wifi P2P interface. */
    public boolean isWifiP2p(String iface) {
        return matchesDownstreamRegexs(iface, tetherableWifiP2pRegexs);
    }

    public boolean isWifiP2pLegacyTetheringMode() {
        return (tetherableWifiP2pRegexs == null || tetherableWifiP2pRegexs.length == 0);
    }

    public boolean isBluetooth(String iface) {
        return matchesDownstreamRegexs(iface, tetherableBluetoothRegexs);
    }
@@ -152,6 +164,7 @@ public class TetheringConfiguration {

        dumpStringArray(pw, "tetherableUsbRegexs", tetherableUsbRegexs);
        dumpStringArray(pw, "tetherableWifiRegexs", tetherableWifiRegexs);
        dumpStringArray(pw, "tetherableWifiP2pRegexs", tetherableWifiP2pRegexs);
        dumpStringArray(pw, "tetherableBluetoothRegexs", tetherableBluetoothRegexs);

        pw.print("isDunRequired: ");
@@ -178,6 +191,7 @@ public class TetheringConfiguration {
        sj.add(String.format("subId:%d", subId));
        sj.add(String.format("tetherableUsbRegexs:%s", makeString(tetherableUsbRegexs)));
        sj.add(String.format("tetherableWifiRegexs:%s", makeString(tetherableWifiRegexs)));
        sj.add(String.format("tetherableWifiP2pRegexs:%s", makeString(tetherableWifiP2pRegexs)));
        sj.add(String.format("tetherableBluetoothRegexs:%s",
                makeString(tetherableBluetoothRegexs)));
        sj.add(String.format("isDunRequired:%s", isDunRequired));
Loading