diff options
| author | 2017-07-05 05:56:29 +0000 | |
|---|---|---|
| committer | 2017-07-05 05:56:29 +0000 | |
| commit | b1eb85c9a8d314461f44a30d37604f7a0eb7315c (patch) | |
| tree | 5bca9b2d776aa78b8ccb6ee3db330fca86e301df | |
| parent | 10c314e19a6b9cdbff9ff8c99ac1923d47966ebb (diff) | |
| parent | 2dce7712f3d974f90336e21cb7fc1cf180e860cc (diff) | |
Merge "Switch to USB_CONFIGURED as the primary USB readiness signal"
| -rw-r--r-- | services/core/java/com/android/server/connectivity/Tethering.java | 35 | ||||
| -rw-r--r-- | tests/net/java/com/android/server/connectivity/TetheringTest.java | 48 |
2 files changed, 75 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index c524033208b2..0a633855d1a4 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -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; @@ -700,7 +701,7 @@ public class Tethering extends BaseNetworkObserver { private void showTetheredNotification(int icon) { NotificationManager notificationManager = - (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE); + (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager == null) { return; } @@ -747,7 +748,7 @@ public class Tethering extends BaseNetworkObserver { private void clearTetheredNotification() { NotificationManager notificationManager = - (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE); + (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager != null && mLastNotificationId != 0) { notificationManager.cancelAsUser(null, mLastNotificationId, UserHandle.ALL); @@ -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) { diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java index 5b4e901f8246..460d53e8f522 100644 --- a/tests/net/java/com/android/server/connectivity/TetheringTest.java +++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java @@ -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); |