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

Commit 26f5bea9 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 6573961 from 3b978c57 to sc-release

Change-Id: If5892acbfd2a4045be554e267b1464df750f038f
parents 06c353af 3b978c57
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -503,9 +503,9 @@ public class DhcpClient extends StateMachine {
     * check whether or not to support caching the last lease info and INIT-REBOOT state.
     *
     * INIT-REBOOT state is supported on Android R by default if there is no experiment flag set to
     * disable this feature explicitly, meanwhile we still hope to be able to control this feature
     * on/off by pushing experiment flag for A/B testing and metrics collection on both of Android
     * Q and R version, however it's disbled on Android Q by default.
     * disable this feature explicitly, meanwhile turning this feature on/off by pushing experiment
     * flag makes it possible to do A/B test and metrics collection on both of Android Q and R, but
     * it's disabled on Android Q by default.
     */
    public boolean isDhcpLeaseCacheEnabled() {
        final boolean defaultEnabled =
+22 −4
Original line number Diff line number Diff line
@@ -482,6 +482,7 @@ public class IpClient extends StateMachine {
    private boolean mMulticastFiltering;
    private long mStartTimeMillis;
    private MacAddress mCurrentBssid;
    private boolean mHasDisabledIPv6OnProvLoss;

    /**
     * Reading the snapshot is an asynchronous operation initiated by invoking
@@ -1137,9 +1138,9 @@ public class IpClient extends StateMachine {
        // Note that we can still be disconnected by IpReachabilityMonitor
        // if the IPv6 default gateway (but not the IPv6 DNS servers; see
        // accompanying code in IpReachabilityMonitor) is unreachable.
        final boolean ignoreIPv6ProvisioningLoss =
                mConfiguration != null && mConfiguration.mUsingMultinetworkPolicyTracker
                && !mCm.shouldAvoidBadWifi();
        final boolean ignoreIPv6ProvisioningLoss = mHasDisabledIPv6OnProvLoss
                || (mConfiguration != null && mConfiguration.mUsingMultinetworkPolicyTracker
                        && !mCm.shouldAvoidBadWifi());

        // Additionally:
        //
@@ -1163,8 +1164,24 @@ public class IpClient extends StateMachine {
        // IPv6 default route then also consider the loss of that default route
        // to be a loss of provisioning. See b/27962810.
        if (oldLp.hasGlobalIpv6Address() && (lostIPv6Router && !ignoreIPv6ProvisioningLoss)) {
            // Although link properties have lost IPv6 default route in this case, if IPv4 is still
            // working with appropriate routes and DNS servers, we can keep the current connection
            // without disconnecting from the network, just disable IPv6 on that given network until
            // to the next provisioning. Disabling IPv6 will result in all IPv6 connectivity torn
            // down and all IPv6 sockets being closed, the non-routable IPv6 DNS servers will be
            // stripped out, so applications will be able to reconnect immediately over IPv4. See
            // b/131781810.
            if (newLp.isIpv4Provisioned()) {
                mInterfaceCtrl.disableIPv6();
                mHasDisabledIPv6OnProvLoss = true;
                delta = PROV_CHANGE_STILL_PROVISIONED;
                if (DBG) {
                    mLog.log("Disable IPv6 stack completely when the default router has gone");
                }
            } else {
                delta = PROV_CHANGE_LOST_PROVISIONING;
            }
        }

        return delta;
    }
@@ -1591,6 +1608,7 @@ public class IpClient extends StateMachine {
        @Override
        public void enter() {
            stopAllIP();
            mHasDisabledIPv6OnProvLoss = false;

            mLinkObserver.clearInterfaceParams();
            resetLinkProperties();
+5 −0
Original line number Diff line number Diff line
@@ -793,6 +793,11 @@ public class NetworkMonitor extends StateMachine {
                    return HANDLED;
                case CMD_FORCE_REEVALUATION:
                case CMD_CAPTIVE_PORTAL_RECHECK:
                    if (getCurrentState() == mDefaultState) {
                        // Before receiving CMD_NETWORK_CONNECTED (when still in mDefaultState),
                        // requests to reevaluate are not valid: drop them.
                        return HANDLED;
                    }
                    String msg = "Forcing reevaluation for UID " + message.arg1;
                    final DnsStallDetector dsd = getDnsStallDetector();
                    if (dsd != null) {
+88 −5
Original line number Diff line number Diff line
@@ -171,6 +171,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -994,7 +995,7 @@ public class IpClientIntegrationTest {
            assertEquals(5, packetList.size());
            assertArpProbe(packetList.get(0));
            assertArpAnnounce(packetList.get(3));

        } else {
            verifyIPv4OnlyProvisioningSuccess(Collections.singletonList(CLIENT_ADDR));
            assertIpMemoryStoreNetworkAttributes(TEST_LEASE_DURATION_S, currentTime,
                    TEST_DEFAULT_MTU);
@@ -1245,11 +1246,11 @@ public class IpClientIntegrationTest {
        fail("No router solicitation received on interface within timeout");
    }

    private void sendBasicRouterAdvertisement(boolean waitForRs) throws Exception {
    private void sendRouterAdvertisement(boolean waitForRs, short lifetime) throws Exception {
        final String dnsServer = "2001:4860:4860::64";
        final ByteBuffer pio = buildPioOption(3600, 1800, "2001:db8:1::/64");
        ByteBuffer rdnss = buildRdnssOption(3600, dnsServer);
        ByteBuffer ra = buildRaPacket(pio, rdnss);
        ByteBuffer ra = buildRaPacket(lifetime, pio, rdnss);

        if (waitForRs) {
            waitForRouterSolicitation();
@@ -1258,6 +1259,14 @@ public class IpClientIntegrationTest {
        mPacketReader.sendResponse(ra);
    }

    private void sendBasicRouterAdvertisement(boolean waitForRs) throws Exception {
        sendRouterAdvertisement(waitForRs, (short) 1800);
    }

    private void sendRouterAdvertisementWithZeroLifetime() throws Exception {
        sendRouterAdvertisement(false /* waitForRs */, (short) 0);
    }

    // TODO: move this and the following method to a common location and use them in ApfTest.
    private static ByteBuffer buildPioOption(int valid, int preferred, String prefixString)
            throws Exception {
@@ -1319,7 +1328,8 @@ public class IpClientIntegrationTest {
        return checksumAdjust(checksum, (short) IPPROTO_TCP, (short) IPPROTO_ICMPV6);
    }

    private static ByteBuffer buildRaPacket(ByteBuffer... options) throws Exception {
    private static ByteBuffer buildRaPacket(short lifetime, ByteBuffer... options)
            throws Exception {
        final MacAddress srcMac = MacAddress.fromString("33:33:00:00:00:01");
        final MacAddress dstMac = MacAddress.fromString("01:02:03:04:05:06");
        final byte[] routerLinkLocal = InetAddresses.parseNumericAddress("fe80::1").getAddress();
@@ -1347,7 +1357,7 @@ public class IpClientIntegrationTest {
        packet.putShort((short) 0);                      // Checksum, TBD
        packet.put((byte) 0);                            // Hop limit, unspecified
        packet.put((byte) 0);                            // M=0, O=0
        packet.putShort((short) 1800);                   // Router lifetime
        packet.putShort(lifetime);                       // Router lifetime
        packet.putInt(0);                                // Reachable time, unspecified
        packet.putInt(100);                              // Retrans time 100ms.

@@ -1367,6 +1377,10 @@ public class IpClientIntegrationTest {
        return packet;
    }

    private static ByteBuffer buildRaPacket(ByteBuffer... options) throws Exception {
        return buildRaPacket((short) 1800, options);
    }

    private void disableIpv6ProvisioningDelays() throws Exception {
        // Speed up the test by disabling DAD and removing router_solicitation_delay.
        // We don't need to restore the default value because the interface is removed in tearDown.
@@ -2153,4 +2167,73 @@ public class IpClientIntegrationTest {
        doDhcpRoamingTest(true /* hasMismatchedIpAddress */, "\"0001docomo\"" /* display name */,
                TEST_DHCP_ROAM_SSID, TEST_DEFAULT_BSSID, true /* expectRoaming */);
    }

    private void doDualStackProvisioning() throws Exception {
        when(mCm.shouldAvoidBadWifi()).thenReturn(true);

        final ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
                .withoutIpReachabilityMonitor()
                .build();
        // Accelerate DHCP handshake to shorten test duration, not strictly necessary.
        mDependencies.setDhcpRapidCommitEnabled(true);
        mIpc.startProvisioning(config);

        final InOrder inOrder = inOrder(mCb);
        final CompletableFuture<LinkProperties> lpFuture = new CompletableFuture<>();
        final String dnsServer = "2001:4860:4860::64";
        final ByteBuffer pio = buildPioOption(3600, 1800, "2001:db8:1::/64");
        final ByteBuffer rdnss = buildRdnssOption(3600, dnsServer);
        final ByteBuffer ra = buildRaPacket(pio, rdnss);

        doIpv6OnlyProvisioning(inOrder, ra);

        // Start IPv4 provisioning and wait until entire provisioning completes.
        handleDhcpPackets(true /* isSuccessLease */, TEST_LEASE_DURATION_S,
                true /* shouldReplyRapidCommitAck */, TEST_DEFAULT_MTU, null /* serverSentUrl */);
        verify(mCb, timeout(TEST_TIMEOUT_MS).atLeastOnce()).onLinkPropertiesChange(argThat(x -> {
            if (!x.isIpv4Provisioned() || !x.isIpv6Provisioned()) return false;
            lpFuture.complete(x);
            return true;
        }));

        final LinkProperties lp = lpFuture.get(TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
        assertNotNull(lp);
        assertTrue(lp.getDnsServers().contains(InetAddress.getByName(dnsServer)));
        assertTrue(lp.getDnsServers().contains(SERVER_ADDR));

        reset(mCb);
    }

    @Test
    public void testIgnoreIpv6ProvisioningLoss() throws Exception {
        doDualStackProvisioning();

        final CompletableFuture<LinkProperties> lpFuture = new CompletableFuture<>();

        // Send RA with 0-lifetime and wait until all IPv6-related default route and DNS servers
        // have been removed, then verify if there is IPv4-only info left in the LinkProperties.
        sendRouterAdvertisementWithZeroLifetime();
        verify(mCb, timeout(TEST_TIMEOUT_MS).atLeastOnce()).onLinkPropertiesChange(
                argThat(x -> {
                    final boolean isOnlyIPv4Provisioned = (x.getLinkAddresses().size() == 1
                            && x.getDnsServers().size() == 1
                            && x.getAddresses().get(0) instanceof Inet4Address
                            && x.getDnsServers().get(0) instanceof Inet4Address);

                    if (!isOnlyIPv4Provisioned) return false;
                    lpFuture.complete(x);
                    return true;
                }));
        final LinkProperties lp = lpFuture.get(TEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
        assertNotNull(lp);
        assertEquals(lp.getAddresses().get(0), CLIENT_ADDR);
        assertEquals(lp.getDnsServers().get(0), SERVER_ADDR);
    }

    @Test
    public void testDualStackProvisioning() throws Exception {
        doDualStackProvisioning();

        verify(mCb, never()).onProvisioningFailure(any());
    }
}
+27 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.after;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeastOnce;
@@ -1229,6 +1230,32 @@ public class NetworkMonitorTest {
        verify(mCapportApiConnection, times(1)).getResponseCode();
    }

    @Test
    public void testIsCaptivePortal_NoRevalidationBeforeNetworkConnected() throws Exception {
        assumeTrue(CaptivePortalDataShimImpl.isSupported());

        final NetworkMonitor nm = makeCellMeteredNetworkMonitor();

        final LinkProperties lp = makeCapportLPs();

        // LinkProperties changed, but NM should not revalidate before notifyNetworkConnected
        nm.notifyLinkPropertiesChanged(lp);
        verify(mHttpConnection, after(100).never()).getResponseCode();
        verify(mHttpsConnection, never()).getResponseCode();
        verify(mCapportApiConnection, never()).getResponseCode();

        setValidProbes();
        setApiContent(mCapportApiConnection, "{'captive': true, "
                + "'user-portal-url': '" + TEST_LOGIN_URL + "'}");

        // After notifyNetworkConnected, validation uses the capport API contents
        nm.notifyNetworkConnected(lp, CELL_METERED_CAPABILITIES);
        verifyNetworkTested(VALIDATION_RESULT_PORTAL, 0 /* probesSucceeded */, TEST_LOGIN_URL);

        verify(mHttpConnection, never()).getResponseCode();
        verify(mCapportApiConnection).getResponseCode();
    }

    @Test
    public void testIsCaptivePortal_CapportApiNotPortalNotValidated() throws Exception {
        assumeTrue(CaptivePortalDataShimImpl.isSupported());