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

Commit b1eb85c9 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Switch to USB_CONFIGURED as the primary USB readiness signal"

parents 10c314e1 2dce7712
Loading
Loading
Loading
Loading
+31 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.connectivity;

import static android.hardware.usb.UsbManager.USB_CONFIGURED;
import static android.hardware.usb.UsbManager.USB_CONNECTED;
import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
import static android.net.ConnectivityManager.getNetworkTypeName;
@@ -786,11 +787,37 @@ public class Tethering extends BaseNetworkObserver {

        private void handleUsbAction(Intent intent) {
            final boolean usbConnected = intent.getBooleanExtra(USB_CONNECTED, false);
            final boolean usbConfigured = intent.getBooleanExtra(USB_CONFIGURED, false);
            final boolean rndisEnabled = intent.getBooleanExtra(USB_FUNCTION_RNDIS, false);

            mLog.log(String.format("USB bcast connected:%s configured:%s rndis:%s",
                    usbConnected, usbConfigured, rndisEnabled));

            // There are three types of ACTION_USB_STATE:
            //
            //     - DISCONNECTED (USB_CONNECTED and USB_CONFIGURED are 0)
            //       Meaning: USB connection has ended either because of
            //       software reset or hard unplug.
            //
            //     - CONNECTED (USB_CONNECTED is 1, USB_CONFIGURED is 0)
            //       Meaning: the first stage of USB protocol handshake has
            //       occurred but it is not complete.
            //
            //     - CONFIGURED (USB_CONNECTED and USB_CONFIGURED are 1)
            //       Meaning: the USB handshake is completely done and all the
            //       functions are ready to use.
            //
            // For more explanation, see b/62552150 .
            if (usbConnected && !usbConfigured) {
                // Nothing for us to do here.
                // TODO: consider ignoring DISCONNECTED broadcasts as well.
                return;
            }

            synchronized (Tethering.this.mPublicSync) {
                mRndisEnabled = rndisEnabled;
                // start tethering if we have a request pending
                if (usbConnected && mRndisEnabled && mUsbTetherRequested) {
                if (usbConfigured && mRndisEnabled && mUsbTetherRequested) {
                    tetherMatchingInterfaces(
                            IControlsTethering.STATE_TETHERED,
                            ConnectivityManager.TETHERING_USB);
@@ -973,7 +1000,7 @@ public class Tethering extends BaseNetworkObserver {

    public int setUsbTethering(boolean enable) {
        if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
        UsbManager usbManager = mContext.getSystemService(UsbManager.class);
        UsbManager usbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);

        synchronized (mPublicSync) {
            if (enable) {
+44 −4
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@

package com.android.server.connectivity;

import static android.hardware.usb.UsbManager.USB_CONFIGURED;
import static android.hardware.usb.UsbManager.USB_CONNECTED;
import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
import static android.net.ConnectivityManager.TETHERING_WIFI;
import static android.net.ConnectivityManager.TETHERING_USB;
import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
@@ -133,6 +138,7 @@ public class TetheringTest {
        public Object getSystemService(String name) {
            if (Context.CONNECTIVITY_SERVICE.equals(name)) return mConnectivityManager;
            if (Context.WIFI_SERVICE.equals(name)) return mWifiManager;
            if (Context.USB_SERVICE.equals(name)) return mUsbManager;
            return super.getSystemService(name);
        }
    }
@@ -145,7 +151,7 @@ public class TetheringTest {
        when(mResources.getStringArray(com.android.internal.R.array.config_tether_usb_regexs))
                .thenReturn(new String[0]);
        when(mResources.getStringArray(com.android.internal.R.array.config_tether_wifi_regexs))
                .thenReturn(new String[]{ "test_wlan\\d" });
                .thenReturn(new String[]{ "test_wlan\\d", "test_rndis\\d" });
        when(mResources.getStringArray(com.android.internal.R.array.config_tether_bluetooth_regexs))
                .thenReturn(new String[0]);
        when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types))
@@ -245,6 +251,14 @@ public class TetheringTest {
        mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
    }

    private void sendUsbBroadcast(boolean connected, boolean configured, boolean rndisFunction) {
        final Intent intent = new Intent(UsbManager.ACTION_USB_STATE);
        intent.putExtra(USB_CONNECTED, connected);
        intent.putExtra(USB_CONFIGURED, configured);
        intent.putExtra(USB_FUNCTION_RNDIS, rndisFunction);
        mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
    }

    private void verifyInterfaceServingModeStarted(boolean ifnameKnown) throws Exception {
        if (!ifnameKnown) {
            verify(mNMService, times(1)).listInterfaces();
@@ -264,6 +278,32 @@ public class TetheringTest {
        mIntents.remove(bcast);
    }

    @Test
    public void testUsbConfiguredBroadcastStartsTethering() throws Exception {
        when(mConnectivityManager.isTetheringSupported()).thenReturn(true);

        // Emulate pressing the USB tethering button in Settings UI.
        mTethering.startTethering(TETHERING_USB, null, false);
        mLooper.dispatchAll();
        verify(mUsbManager, times(1)).setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS, false);

        // Pretend we receive a USB connected broadcast. Here we also pretend
        // that the RNDIS function is somehow enabled, so that we see if we
        // might trip ourselves up.
        sendUsbBroadcast(true, false, true);
        mLooper.dispatchAll();
        // This should produce no activity of any kind.
        verifyNoMoreInteractions(mConnectivityManager);
        verifyNoMoreInteractions(mNMService);

        // Pretend we then receive USB configured broadcast.
        sendUsbBroadcast(true, true, true);
        mLooper.dispatchAll();
        // Now we should see the start of tethering mechanics (in this case:
        // tetherMatchingInterfaces() which starts by fetching all interfaces).
        verify(mNMService, times(1)).listInterfaces();
    }

    public void workingLocalOnlyHotspot(
            boolean withInterfaceStateChanged, boolean enrichedApBroadcast) throws Exception {
        when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
@@ -341,7 +381,7 @@ public class TetheringTest {
        when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);

        // Emulate pressing the WiFi tethering button.
        mTethering.startTethering(ConnectivityManager.TETHERING_WIFI, null, false);
        mTethering.startTethering(TETHERING_WIFI, null, false);
        mLooper.dispatchAll();
        verify(mWifiManager, times(1)).startSoftAp(null);
        verifyNoMoreInteractions(mWifiManager);
@@ -391,7 +431,7 @@ public class TetheringTest {
        /////

        // Emulate pressing the WiFi tethering button.
        mTethering.stopTethering(ConnectivityManager.TETHERING_WIFI);
        mTethering.stopTethering(TETHERING_WIFI);
        mLooper.dispatchAll();
        verify(mWifiManager, times(1)).stopSoftAp();
        verifyNoMoreInteractions(mWifiManager);
@@ -436,7 +476,7 @@ public class TetheringTest {
        doThrow(new RemoteException()).when(mNMService).setIpForwardingEnabled(true);

        // Emulate pressing the WiFi tethering button.
        mTethering.startTethering(ConnectivityManager.TETHERING_WIFI, null, false);
        mTethering.startTethering(TETHERING_WIFI, null, false);
        mLooper.dispatchAll();
        verify(mWifiManager, times(1)).startSoftAp(null);
        verifyNoMoreInteractions(mWifiManager);