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

Commit 30f2544f authored by Hugo Benichi's avatar Hugo Benichi Committed by Gerrit Code Review
Browse files

Merge "Add a method to start the captive portal login app."

parents 1bc1936a 2965d33a
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package android.net;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
@@ -3467,6 +3468,22 @@ public class ConnectivityManager {
        }
    }

    /**
     * Requests that the system open the captive portal app on the specified network.
     *
     * @param network The network to log into.
     *
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
    public void startCaptivePortalApp(Network network) {
        try {
            mService.startCaptivePortalApp(network);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * It is acceptable to briefly use multipath data to provide seamless connectivity for
     * time-sensitive user-facing operations when the system default network is temporarily
+1 −0
Original line number Diff line number Diff line
@@ -161,6 +161,7 @@ interface IConnectivityManager

    void setAcceptUnvalidated(in Network network, boolean accept, boolean always);
    void setAvoidUnvalidated(in Network network);
    void startCaptivePortalApp(in Network network);

    int getMultipathPreference(in Network Network);

+11 −0
Original line number Diff line number Diff line
@@ -2764,6 +2764,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
                PROMPT_UNVALIDATED_DELAY_MS);
    }

    @Override
    public void startCaptivePortalApp(Network network) {
        enforceConnectivityInternalPermission();
        mHandler.post(() -> {
            NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
            if (nai == null) return;
            if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return;
            nai.networkMonitor.sendMessage(NetworkMonitor.CMD_LAUNCH_CAPTIVE_PORTAL_APP);
        });
    }

    public boolean avoidBadWifi() {
        return mMultinetworkPolicyTracker.getAvoidBadWifi();
    }
+5 −3
Original line number Diff line number Diff line
@@ -197,11 +197,13 @@ public class NetworkMonitor extends StateMachine {
    public static final int EVENT_PROVISIONING_NOTIFICATION = BASE + 10;

    /**
     * Message to self indicating sign-in app should be launched.
     * Message indicating sign-in app should be launched.
     * Sent by mLaunchCaptivePortalAppBroadcastReceiver when the
     * user touches the sign in notification.
     * user touches the sign in notification, or sent by
     * ConnectivityService when the user touches the "sign into
     * network" button in the wifi access point detail page.
     */
    private static final int CMD_LAUNCH_CAPTIVE_PORTAL_APP = BASE + 11;
    public static final int CMD_LAUNCH_CAPTIVE_PORTAL_APP = BASE + 11;

    /**
     * Retest network to see if captive portal is still in place.
+71 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.net.CaptivePortal;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.ConnectivityManager.PacketKeepalive;
@@ -78,6 +79,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.test.AndroidTestCase;
import android.test.mock.MockContentResolver;
@@ -121,7 +123,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
    private static final int TIMEOUT_MS = 500;
    private static final int TEST_LINGER_DELAY_MS = 120;

    private BroadcastInterceptingContext mServiceContext;
    private MockContext mServiceContext;
    private WrappedConnectivityService mService;
    private WrappedConnectivityManager mCm;
    private MockNetworkAgent mWiFiNetworkAgent;
@@ -152,6 +154,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        private final MockContentResolver mContentResolver;

        @Spy private Resources mResources;
        private final LinkedBlockingQueue<Intent> mStartedActivities = new LinkedBlockingQueue<>();

        MockContext(Context base) {
            super(base);
@@ -168,6 +171,27 @@ public class ConnectivityServiceTest extends AndroidTestCase {
            mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
        }

        @Override
        public void startActivityAsUser(Intent intent, UserHandle handle) {
            mStartedActivities.offer(intent);
        }

        public Intent expectStartActivityIntent(int timeoutMs) {
            Intent intent = null;
            try {
                intent = mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {}
            assertNotNull("Did not receive sign-in intent after " + timeoutMs + "ms", intent);
            return intent;
        }

        public void expectNoStartActivityIntent(int timeoutMs) {
            try {
                assertNull("Received unexpected Intent to start activity",
                        mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS));
            } catch (InterruptedException e) {}
        }

        @Override
        public Object getSystemService(String name) {
            if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
@@ -1922,6 +1946,52 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
    }

    @SmallTest
    public void testCaptivePortalApp() {
        final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
        final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
                .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
        mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);

        final TestNetworkCallback validatedCallback = new TestNetworkCallback();
        final NetworkRequest validatedRequest = new NetworkRequest.Builder()
                .addCapability(NET_CAPABILITY_VALIDATED).build();
        mCm.registerNetworkCallback(validatedRequest, validatedCallback);

        // Bring up wifi.
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        mWiFiNetworkAgent.connect(true);
        validatedCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
        Network wifiNetwork = mWiFiNetworkAgent.getNetwork();

        // Check that calling startCaptivePortalApp does nothing.
        final int fastTimeoutMs = 100;
        mCm.startCaptivePortalApp(wifiNetwork);
        mServiceContext.expectNoStartActivityIntent(fastTimeoutMs);

        // Turn into a captive portal.
        mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 302;
        mCm.reportNetworkConnectivity(wifiNetwork, false);
        captivePortalCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
        validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);

        // Check that startCaptivePortalApp sends the expected intent.
        mCm.startCaptivePortalApp(wifiNetwork);
        Intent intent = mServiceContext.expectStartActivityIntent(TIMEOUT_MS);
        assertEquals(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN, intent.getAction());
        assertEquals(wifiNetwork, intent.getExtra(ConnectivityManager.EXTRA_NETWORK));

        // Have the app report that the captive portal is dismissed, and check that we revalidate.
        mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 204;
        CaptivePortal c = (CaptivePortal) intent.getExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL);
        c.reportCaptivePortalDismissed();
        validatedCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
        captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);

        mCm.unregisterNetworkCallback(validatedCallback);
        mCm.unregisterNetworkCallback(captivePortalCallback);
    }

    @SmallTest
    public void testAvoidOrIgnoreCaptivePortals() {
        final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();