diff --git a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java index 9d19335bcb..f8dd673a21 100644 --- a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java +++ b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java @@ -533,8 +533,9 @@ public class UpstreamNetworkMonitor { @Override public void onLinkPropertiesChanged(Network network, LinkProperties newLp) { + handleLinkProp(network, newLp); + if (mCallbackType == CALLBACK_DEFAULT_INTERNET) { - updateLinkProperties(network, newLp); // When the default network callback calls onLinkPropertiesChanged, it means that // all the network information for the default network is known (because // onLinkPropertiesChanged is called after onAvailable and onCapabilitiesChanged). @@ -543,7 +544,6 @@ public class UpstreamNetworkMonitor { return; } - handleLinkProp(network, newLp); // Any non-LISTEN_ALL callback will necessarily concern a network that will // also match the LISTEN_ALL callback by construction of the LISTEN_ALL callback. // So it's not useful to do this work for non-LISTEN_ALL callbacks. diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TestConnectivityManager.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TestConnectivityManager.java index e692015366..b2cbf7560e 100644 --- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TestConnectivityManager.java +++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TestConnectivityManager.java @@ -186,6 +186,16 @@ public class TestConnectivityManager extends ConnectivityManager { makeDefaultNetwork(agent, BROADCAST_FIRST, null /* inBetween */); } + void sendLinkProperties(TestNetworkAgent agent, boolean updateDefaultFirst) { + if (!updateDefaultFirst) agent.sendLinkProperties(); + + for (NetworkCallback cb : mTrackingDefault.keySet()) { + cb.onLinkPropertiesChanged(agent.networkId, agent.linkProperties); + } + + if (updateDefaultFirst) agent.sendLinkProperties(); + } + static boolean looksLikeDefaultRequest(NetworkRequest req) { return req.hasCapability(NET_CAPABILITY_INTERNET) && !req.hasCapability(NET_CAPABILITY_DUN) diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java index 173679dc31..97cebd8477 100644 --- a/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java +++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java @@ -577,6 +577,67 @@ public class UpstreamNetworkMonitorTest { verify(mEntitleMgr, times(1)).maybeRunProvisioning(); } + @Test + public void testLinkAddressChanged() { + final String ipv4Addr = "100.112.103.18/24"; + final String ipv6Addr1 = "2001:db8:4:fd00:827a:bfff:fe6f:374d/64"; + final String ipv6Addr2 = "2003:aa8:3::123/64"; + mUNM.startTrackDefaultNetwork(mEntitleMgr); + mUNM.startObserveAllNetworks(); + mUNM.setUpstreamConfig(true /* autoUpstream */, false /* dunRequired */); + mUNM.setTryCell(true); + + final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, CELL_CAPABILITIES); + final LinkProperties cellLp = cellAgent.linkProperties; + cellLp.setInterfaceName("rmnet0"); + addLinkAddresses(cellLp, ipv4Addr); + cellAgent.fakeConnect(); + mCM.makeDefaultNetwork(cellAgent); + mLooper.dispatchAll(); + verifyCurrentLinkProperties(cellAgent); + int messageIndex = mSM.messages.size() - 1; + + addLinkAddresses(cellLp, ipv6Addr1); + mCM.sendLinkProperties(cellAgent, false /* updateDefaultFirst */); + mLooper.dispatchAll(); + verifyCurrentLinkProperties(cellAgent); + verifyNotifyLinkPropertiesChange(messageIndex); + messageIndex = mSM.messages.size() - 1; + + removeLinkAddresses(cellLp, ipv6Addr1); + addLinkAddresses(cellLp, ipv6Addr2); + mCM.sendLinkProperties(cellAgent, true /* updateDefaultFirst */); + mLooper.dispatchAll(); + assertEquals(cellAgent.linkProperties, mUNM.getCurrentPreferredUpstream().linkProperties); + verifyCurrentLinkProperties(cellAgent); + verifyNotifyLinkPropertiesChange(messageIndex); + } + + private void verifyCurrentLinkProperties(TestNetworkAgent agent) { + assertEquals(agent.networkId, mUNM.getCurrentPreferredUpstream().network); + assertEquals(agent.linkProperties, mUNM.getCurrentPreferredUpstream().linkProperties); + } + + private void verifyNotifyLinkPropertiesChange(int lastMessageIndex) { + assertEquals(UpstreamNetworkMonitor.EVENT_ON_LINKPROPERTIES, + mSM.messages.get(++lastMessageIndex).arg1); + assertEquals(UpstreamNetworkMonitor.NOTIFY_LOCAL_PREFIXES, + mSM.messages.get(++lastMessageIndex).arg1); + assertEquals(lastMessageIndex + 1, mSM.messages.size()); + } + + private void addLinkAddresses(LinkProperties lp, String... addrs) { + for (String addrStr : addrs) { + lp.addLinkAddress(new LinkAddress(addrStr)); + } + } + + private void removeLinkAddresses(LinkProperties lp, String... addrs) { + for (String addrStr : addrs) { + lp.removeLinkAddress(new LinkAddress(addrStr)); + } + } + private void assertSatisfiesLegacyType(int legacyType, UpstreamNetworkState ns) { if (legacyType == TYPE_NONE) { assertTrue(ns == null);