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

Commit 9223abcb authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 6282804 from faac06e3 to rvc-release

Change-Id: I6ef0a0e94e9cc16100663f589dcd6cbd2a221bc6
parents 7957dbc2 faac06e3
Loading
Loading
Loading
Loading
+29 −1
Original line number Diff line number Diff line
@@ -141,6 +141,14 @@ public class NetworkStackUtils {
     */
    public static final String DHCP_IP_CONFLICT_DETECT_VERSION = "dhcp_ip_conflict_detect_version";

    /**
     * Minimum module version at which to enable dismissal CaptivePortalLogin app in validated
     * network feature. CaptivePortalLogin app will also use validation facilities in
     * {@link NetworkMonitor} to perform portal validation if feature is enabled.
     */
    public static final String DISMISS_PORTAL_IN_VALIDATED_NETWORK =
            "dismiss_portal_in_validated_network";

    static {
        System.loadLibrary("networkstackutilsjni");
    }
@@ -270,12 +278,32 @@ public class NetworkStackUtils {
     */
    public static boolean isFeatureEnabled(@NonNull Context context, @NonNull String namespace,
            @NonNull String name) {
        final int propertyVersion = getDeviceConfigPropertyInt(namespace, name,
                0 /* default value */);
        return isFeatureEnabled(context, namespace, name, false);
    }

    /**
     * Check whether or not one specific experimental feature for a particular namespace from
     * {@link DeviceConfig} is enabled by comparing NetworkStack module version {@link NetworkStack}
     * with current version of property. If this property version is valid, the corresponding
     * experimental feature would be enabled, otherwise disabled.
     * @param context The global context information about an app environment.
     * @param namespace The namespace containing the property to look up.
     * @param name The name of the property to look up.
     * @param defaultEnabled The value to return if the property does not exist or its value is
     *                       null.
     * @return true if this feature is enabled, or false if disabled.
     */
    public static boolean isFeatureEnabled(@NonNull Context context, @NonNull String namespace,
            @NonNull String name, boolean defaultEnabled) {
        try {
            final int propertyVersion = getDeviceConfigPropertyInt(namespace, name,
                    0 /* default value */);
            final long packageVersion = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), 0).getLongVersionCode();
            return (propertyVersion != 0 && packageVersion >= (long) propertyVersion);
            return (propertyVersion == 0 && defaultEnabled)
                    || (propertyVersion != 0 && packageVersion >= (long) propertyVersion);
        } catch (NameNotFoundException e) {
            Log.e(TAG, "Could not find the package name", e);
            return false;
+32 −1
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_PROMPT;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USER_AGENT;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS;
import static android.net.util.NetworkStackUtils.DISMISS_PORTAL_IN_VALIDATED_NETWORK;
import static android.net.util.NetworkStackUtils.isEmpty;
import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;

@@ -960,7 +961,11 @@ public class NetworkMonitor extends StateMachine {
                    final Network network = new Network(mCleartextDnsNetwork);
                    appExtras.putParcelable(ConnectivityManager.EXTRA_NETWORK, network);
                    final CaptivePortalProbeResult probeRes = mLastPortalProbeResult;
                    appExtras.putString(EXTRA_CAPTIVE_PORTAL_URL, probeRes.detectUrl);
                    // Use redirect URL from AP if exists.
                    final String portalUrl =
                            (useRedirectUrlForPortal() && probeRes.redirectUrl != null)
                            ? probeRes.redirectUrl : probeRes.detectUrl;
                    appExtras.putString(EXTRA_CAPTIVE_PORTAL_URL, portalUrl);
                    if (probeRes.probeSpec != null) {
                        final String encodedSpec = probeRes.probeSpec.getEncodedSpec();
                        appExtras.putString(EXTRA_CAPTIVE_PORTAL_PROBE_SPEC, encodedSpec);
@@ -977,6 +982,15 @@ public class NetworkMonitor extends StateMachine {
            }
        }

        private boolean useRedirectUrlForPortal() {
            // It must match the conditions in CaptivePortalLogin in which the redirect URL is not
            // used to validate that the portal is gone.
            final boolean aboveQ =
                    ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.Q);
            return aboveQ && mDependencies.isFeatureEnabled(mContext, NAMESPACE_CONNECTIVITY,
                    DISMISS_PORTAL_IN_VALIDATED_NETWORK, aboveQ /* defaultEnabled */);
        }

        @Override
        public void exit() {
            if (mLaunchCaptivePortalAppBroadcastReceiver != null) {
@@ -2385,6 +2399,23 @@ public class NetworkMonitor extends StateMachine {
                    NetworkMonitorUtils.PERMISSION_ACCESS_NETWORK_CONDITIONS);
        }

        /**
         * Check whether or not one specific experimental feature for a particular namespace from
         * {@link DeviceConfig} is enabled by comparing NetworkStack module version
         * {@link NetworkStack} with current version of property. If this property version is valid,
         * the corresponding experimental feature would be enabled, otherwise disabled.
         * @param context The global context information about an app environment.
         * @param namespace The namespace containing the property to look up.
         * @param name The name of the property to look up.
         * @param defaultEnabled The value to return if the property does not exist or its value is
         *                       null.
         * @return true if this feature is enabled, or false if disabled.
         */
        public boolean isFeatureEnabled(@NonNull Context context, @NonNull String namespace,
                @NonNull String name, boolean defaultEnabled) {
            return NetworkStackUtils.isFeatureEnabled(context, namespace, name, defaultEnabled);
        }

        public static final Dependencies DEFAULT = new Dependencies();
    }

+56 −1
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import static android.net.util.DataStallUtils.DATA_STALL_EVALUATION_TYPE_TCP;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS;
import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS;
import static android.net.util.NetworkStackUtils.DISMISS_PORTAL_IN_VALIDATED_NETWORK;

import static com.android.networkstack.apishim.ConstantsShim.DETECTION_METHOD_DNS_EVENTS;
import static com.android.networkstack.apishim.ConstantsShim.DETECTION_METHOD_TCP_METRICS;
@@ -59,6 +60,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
@@ -478,6 +480,7 @@ public class NetworkMonitorTest {

        mCreatedNetworkMonitors = new HashSet<>();
        mRegisteredReceivers = new HashSet<>();
        setDismissPortalInValidatedNetwork(false);
    }

    @After
@@ -1087,7 +1090,7 @@ public class NetworkMonitorTest {
    public void testLaunchCaptivePortalApp() throws Exception {
        setSslException(mHttpsConnection);
        setPortal302(mHttpConnection);

        when(mHttpConnection.getHeaderField(eq("location"))).thenReturn(TEST_LOGIN_URL);
        final NetworkMonitor nm = makeMonitor(METERED_CAPABILITIES);
        notifyNetworkConnected(nm, METERED_CAPABILITIES);

@@ -1111,6 +1114,9 @@ public class NetworkMonitorTest {
        // framework and only intended for the captive portal app, but the framework needs
        // the network to identify the right NetworkMonitor.
        assertEquals(TEST_NETID, networkCaptor.getValue().netId);
        // Portal URL should be detection URL.
        final String redirectUrl = bundle.getString(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL);
        assertEquals(TEST_HTTP_URL, redirectUrl);

        // Have the app report that the captive portal is dismissed, and check that we revalidate.
        setStatus(mHttpsConnection, 204);
@@ -1442,6 +1448,50 @@ public class NetworkMonitorTest {
                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID), any());
    }

    @Test
    public void testDismissPortalInValidatedNetworkEnabledOsSupported() throws Exception {
        assumeTrue(ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.Q));
        testDismissPortalInValidatedNetworkEnabled(TEST_LOGIN_URL);
    }

    @Test
    public void testDismissPortalInValidatedNetworkEnabledOsNotSupported() throws Exception {
        assumeFalse(ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.Q));
        testDismissPortalInValidatedNetworkEnabled(TEST_HTTP_URL);
    }

    private void testDismissPortalInValidatedNetworkEnabled(String portalUrl) throws Exception {
        setDismissPortalInValidatedNetwork(true);
        setSslException(mHttpsConnection);
        setPortal302(mHttpConnection);
        when(mHttpConnection.getHeaderField(eq("location"))).thenReturn(TEST_LOGIN_URL);
        final NetworkMonitor nm = makeMonitor(METERED_CAPABILITIES);
        notifyNetworkConnected(nm, METERED_CAPABILITIES);

        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
            .showProvisioningNotification(any(), any());

        assertEquals(1, mRegisteredReceivers.size());
        // Check that startCaptivePortalApp sends the expected intent.
        nm.launchCaptivePortalApp();

        final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
        final ArgumentCaptor<Network> networkCaptor = ArgumentCaptor.forClass(Network.class);
        verify(mCm, timeout(HANDLER_TIMEOUT_MS).times(1))
            .startCaptivePortalApp(networkCaptor.capture(), bundleCaptor.capture());
        verify(mNotifier).notifyCaptivePortalValidationPending(networkCaptor.getValue());
        final Bundle bundle = bundleCaptor.getValue();
        final Network bundleNetwork = bundle.getParcelable(ConnectivityManager.EXTRA_NETWORK);
        assertEquals(TEST_NETID, bundleNetwork.netId);
        // Network is passed both in bundle and as parameter, as the bundle is opaque to the
        // framework and only intended for the captive portal app, but the framework needs
        // the network to identify the right NetworkMonitor.
        assertEquals(TEST_NETID, networkCaptor.getValue().netId);
        // Portal URL should be redirect URL.
        final String redirectUrl = bundle.getString(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL);
        assertEquals(portalUrl, redirectUrl);
    }

    @Test
    public void testEvaluationState_clearProbeResults() throws Exception {
        final NetworkMonitor nm = runValidatedNetworkTest();
@@ -1602,6 +1652,11 @@ public class NetworkMonitorTest {
                eq(Settings.Global.CAPTIVE_PORTAL_MODE), anyInt())).thenReturn(mode);
    }

    private void setDismissPortalInValidatedNetwork(boolean enabled) {
        when(mDependencies.isFeatureEnabled(any(), any(),
                eq(DISMISS_PORTAL_IN_VALIDATED_NETWORK), anyBoolean())).thenReturn(enabled);
    }

    private void runPortalNetworkTest(int result) {
        runNetworkTest(result);
        assertEquals(1, mRegisteredReceivers.size());