diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java index b4e578116b..2e71fdae73 100644 --- a/Tethering/src/com/android/networkstack/tethering/Tethering.java +++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java @@ -88,7 +88,6 @@ import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; -import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.TetherStatesParcel; import android.net.TetheredClient; @@ -1856,7 +1855,11 @@ public class Tethering { final Network newUpstream = (ns != null) ? ns.network : null; if (mTetherUpstream != newUpstream) { mTetherUpstream = newUpstream; - reportUpstreamChanged(ns); + reportUpstreamChanged(mTetherUpstream); + // Need to notify capabilities change after upstream network changed because new + // network's capabilities should be checked every time. + mNotificationUpdater.onUpstreamCapabilitiesChanged( + (ns != null) ? ns.networkCapabilities : null); } } @@ -2084,6 +2087,7 @@ public class Tethering { if (mTetherUpstream != null) { mTetherUpstream = null; reportUpstreamChanged(null); + mNotificationUpdater.onUpstreamCapabilitiesChanged(null); } mBpfCoordinator.stopPolling(); } @@ -2438,10 +2442,8 @@ public class Tethering { } } - private void reportUpstreamChanged(UpstreamNetworkState ns) { + private void reportUpstreamChanged(final Network network) { final int length = mTetheringEventCallbacks.beginBroadcast(); - final Network network = (ns != null) ? ns.network : null; - final NetworkCapabilities capabilities = (ns != null) ? ns.networkCapabilities : null; try { for (int i = 0; i < length; i++) { try { @@ -2453,9 +2455,6 @@ public class Tethering { } finally { mTetheringEventCallbacks.finishBroadcast(); } - // Need to notify capabilities change after upstream network changed because new network's - // capabilities should be checked every time. - mNotificationUpdater.onUpstreamCapabilitiesChanged(capabilities); } private void reportConfigurationChanged(TetheringConfigurationParcel config) { diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java index a63b364663..98a3b1dcfa 100644 --- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java +++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java @@ -2678,12 +2678,19 @@ public class TetheringTest { public void testUpstreamNetworkChanged() { final Tethering.TetherMainSM stateMachine = (Tethering.TetherMainSM) mTetheringDependencies.mUpstreamNetworkMonitorSM; + // Gain upstream. final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState(); initTetheringUpstream(upstreamState); stateMachine.chooseUpstreamType(true); - mTetheringEventCallback.expectUpstreamChanged(upstreamState.network); - verify(mNotificationUpdater, times(1)).onUpstreamCapabilitiesChanged(any()); + verify(mNotificationUpdater) + .onUpstreamCapabilitiesChanged(upstreamState.networkCapabilities); + + // Lose upstream. + initTetheringUpstream(null); + stateMachine.chooseUpstreamType(true); + mTetheringEventCallback.expectUpstreamChanged(NULL_NETWORK); + verify(mNotificationUpdater).onUpstreamCapabilitiesChanged(null); } @Test @@ -2697,7 +2704,8 @@ public class TetheringTest { stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState); // Should have two onUpstreamCapabilitiesChanged(). // One is called by reportUpstreamChanged(). One is called by EVENT_ON_CAPABILITIES. - verify(mNotificationUpdater, times(2)).onUpstreamCapabilitiesChanged(any()); + verify(mNotificationUpdater, times(2)) + .onUpstreamCapabilitiesChanged(upstreamState.networkCapabilities); reset(mNotificationUpdater); // Verify that onUpstreamCapabilitiesChanged won't be called if not current upstream network @@ -2709,6 +2717,27 @@ public class TetheringTest { verify(mNotificationUpdater, never()).onUpstreamCapabilitiesChanged(any()); } + @Test + public void testUpstreamCapabilitiesChanged_startStopTethering() throws Exception { + final TestNetworkAgent wifi = new TestNetworkAgent(mCm, buildWifiUpstreamState()); + + // Start USB tethering with no current upstream. + prepareUsbTethering(); + sendUsbBroadcast(true, true, TETHER_USB_RNDIS_FUNCTION); + + // Pretend wifi connected and expect the upstream to be set. + wifi.fakeConnect(); + mCm.makeDefaultNetwork(wifi, CALLBACKS_FIRST); + mLooper.dispatchAll(); + verify(mNotificationUpdater).onUpstreamCapabilitiesChanged( + wifi.networkCapabilities); + + // Stop tethering. + // Expect that TetherModeAliveState#exit sends capabilities change notification to null. + runStopUSBTethering(); + verify(mNotificationUpdater).onUpstreamCapabilitiesChanged(null); + } + @Test public void testDumpTetheringLog() throws Exception { final FileDescriptor mockFd = mock(FileDescriptor.class);