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

Commit 973eff2e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add prompt to sign in at captive portal to Wi-Fi Slice" into qt-dev

parents 83f60c81 8f6c0697
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -68,16 +68,17 @@ public abstract class SliceBackgroundWorker<E> implements Closeable {
    }

    /**
     * Returns the singleton instance of the {@link SliceBackgroundWorker} for specified {@link Uri}
     * if exists
     * Returns the singleton instance of {@link SliceBackgroundWorker} for specified {@link Uri} if
     * exists
     */
    @Nullable
    public static SliceBackgroundWorker getInstance(Uri uri) {
        return LIVE_WORKERS.get(uri);
    @SuppressWarnings("TypeParameterUnusedInFormals")
    public static <T extends SliceBackgroundWorker> T getInstance(Uri uri) {
        return (T) LIVE_WORKERS.get(uri);
    }

    /**
     * Returns the singleton instance of the {@link SliceBackgroundWorker} for specified {@link
     * Returns the singleton instance of {@link SliceBackgroundWorker} for specified {@link
     * CustomSliceable}
     */
    static SliceBackgroundWorker getInstance(Context context, Sliceable sliceable, Uri uri) {
+8 −1
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.settings.wifi.slice;

import android.app.Activity;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.wifi.WifiManager;
import android.os.Bundle;

@@ -36,10 +38,15 @@ public class ConnectToWifiHandler extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final Network network = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_NETWORK);
        final Bundle accessPointState = getIntent().getBundleExtra(
                WifiDialogActivity.KEY_ACCESS_POINT_STATE);

        if (accessPointState != null) {
        if (network != null) {
            final ConnectivityManager cm = getSystemService(ConnectivityManager.class);
            // start captive portal app to sign in to network
            cm.startCaptivePortalApp(network);
        } else if (accessPointState != null) {
            connect(new AccessPoint(this, accessPointState));
        }
        finish();
+5 −1
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ public class ContextualWifiSlice extends WifiSlice {
            sActiveUiSession = currentUiSession;
            sPreviouslyDisplayed = false;
        }
        if (!sPreviouslyDisplayed && !TextUtils.equals(getActiveSSID(), WifiSsid.NONE)) {
        if (!sPreviouslyDisplayed && hasWorkingNetwork()) {
            Log.d(TAG, "Wifi is connected, no point showing any suggestion.");
            return null;
        }
@@ -67,4 +67,8 @@ public class ContextualWifiSlice extends WifiSlice {

        return super.getSlice();
    }

    private boolean hasWorkingNetwork() {
        return !TextUtils.equals(getActiveSSID(), WifiSsid.NONE) && !isCaptivePortal();
    }
}
+91 −3
Original line number Diff line number Diff line
@@ -16,14 +16,27 @@

package com.android.settings.wifi.slice;

import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.VisibleForTesting;

import com.android.internal.util.Preconditions;
import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settings.wifi.WifiUtils;
import com.android.settingslib.wifi.AccessPoint;
import com.android.settingslib.wifi.WifiTracker;

@@ -33,16 +46,23 @@ import java.util.List;
/**
 * {@link SliceBackgroundWorker} for Wi-Fi, used by WifiSlice.
 */
public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint>
        implements WifiTracker.WifiListener {
public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> implements
        WifiTracker.WifiListener {

    private static final String TAG = "WifiScanWorker";

    @VisibleForTesting
    CaptivePortalNetworkCallback mCaptivePortalNetworkCallback;

    private final Context mContext;

    private WifiTracker mWifiTracker;
    private ConnectivityManager mConnectivityManager;

    public WifiScanWorker(Context context, Uri uri) {
        super(context, uri);
        mContext = context;
        mConnectivityManager = context.getSystemService(ConnectivityManager.class);
    }

    @Override
@@ -58,6 +78,7 @@ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint>
    @Override
    protected void onSliceUnpinned() {
        mWifiTracker.onStop();
        unregisterCaptivePortalNetworkCallback();
    }

    @Override
@@ -124,4 +145,71 @@ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint>
        }
        return null;
    }

    public void registerCaptivePortalNetworkCallback(Network wifiNetwork) {
        if (wifiNetwork == null) {
            return;
        }

        if (mCaptivePortalNetworkCallback != null
                && mCaptivePortalNetworkCallback.isSameNetwork(wifiNetwork)) {
            return;
        }

        unregisterCaptivePortalNetworkCallback();

        mCaptivePortalNetworkCallback = new CaptivePortalNetworkCallback(wifiNetwork);
        mConnectivityManager.registerNetworkCallback(
                new NetworkRequest.Builder()
                        .clearCapabilities()
                        .addTransportType(TRANSPORT_WIFI)
                        .build(),
                mCaptivePortalNetworkCallback,
                new Handler(Looper.getMainLooper()));
    }

    public void unregisterCaptivePortalNetworkCallback() {
        if (mCaptivePortalNetworkCallback != null) {
            try {
                mConnectivityManager.unregisterNetworkCallback(mCaptivePortalNetworkCallback);
            } catch (RuntimeException e) {
                Log.e(TAG, "Unregistering CaptivePortalNetworkCallback failed.", e);
            }
            mCaptivePortalNetworkCallback = null;
        }
    }

    class CaptivePortalNetworkCallback extends NetworkCallback {

        private final Network mNetwork;
        private boolean mIsCaptivePortal;

        CaptivePortalNetworkCallback(Network network) {
            mNetwork = Preconditions.checkNotNull(network);
        }

        @Override
        public void onCapabilitiesChanged(Network network,
                NetworkCapabilities networkCapabilities) {
            if (!mNetwork.equals(network)) {
                return;
            }

            final boolean isCaptivePortal = WifiUtils.canSignIntoNetwork(networkCapabilities);
            if (mIsCaptivePortal == isCaptivePortal) {
                return;
            }

            mIsCaptivePortal = isCaptivePortal;
            notifySliceChange();
        }

        /**
         * Returns true if the supplied network is not null and is the same as the originally
         * supplied value.
         */
        public boolean isSameNetwork(Network network) {
            return mNetwork.equals(network);
        }
    }
}
+55 −10
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
import android.net.NetworkInfo.DetailedState;
@@ -78,10 +80,12 @@ public class WifiSlice implements CustomSliceable {

    protected final Context mContext;
    protected final WifiManager mWifiManager;
    protected final ConnectivityManager mConnectivityManager;

    public WifiSlice(Context context) {
        mContext = context;
        mWifiManager = mContext.getSystemService(WifiManager.class);
        mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
    }

    @Override
@@ -100,13 +104,16 @@ public class WifiSlice implements CustomSliceable {
            return listBuilder.build();
        }

        final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(getUri());
        final WifiScanWorker worker = SliceBackgroundWorker.getInstance(getUri());
        final List<AccessPoint> results = worker != null ? worker.getResults() : null;
        final int apCount = results == null ? 0 : results.size();
        final boolean isFirstApActive = apCount > 0 && results.get(0).isActive();
        handleCaptivePortalCallback(worker, isFirstApActive);

        // Need a loading text when results are not ready or out of date.
        boolean needLoadingRow = true;
        int index = apCount > 0 && results.get(0).isActive() ? 1 : 0;
        // Skip checking the existence of the first access point if it's active
        int index = isFirstApActive ? 1 : 0;
        // This loop checks the existence of reachable APs to determine the validity of the current
        // AP list.
        for (; index < apCount; index++) {
@@ -159,20 +166,36 @@ public class WifiSlice implements CustomSliceable {
                        .setPrimaryAction(primarySliceAction));
    }

    private void handleCaptivePortalCallback(WifiScanWorker worker, boolean isFirstApActive) {
        if (worker == null) {
            return;
        }
        if (isFirstApActive) {
            worker.registerCaptivePortalNetworkCallback(mWifiManager.getCurrentNetwork());
        } else {
            worker.unregisterCaptivePortalNetworkCallback();
        }
    }

    private ListBuilder.RowBuilder getAccessPointRow(AccessPoint accessPoint) {
        final CharSequence title = getAccessPointName(accessPoint);
        final IconCompat levelIcon = getAccessPointLevelIcon(accessPoint);
        final boolean isCaptivePortal = accessPoint.isActive() && isCaptivePortal();
        final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder()
                .setTitleItem(levelIcon, ListBuilder.ICON_IMAGE)
                .setSubtitle(title)
                .setPrimaryAction(SliceAction.create(
                        getAccessPointAction(accessPoint), levelIcon, ListBuilder.ICON_IMAGE,
                        title));
                .setPrimaryAction(SliceAction.createDeeplink(
                        getAccessPointAction(accessPoint, isCaptivePortal), levelIcon,
                        ListBuilder.ICON_IMAGE, title));

        if (isCaptivePortal) {
            rowBuilder.addEndItem(getCaptivePortalEndAction(accessPoint, title));
        } else {
            final IconCompat endIcon = getEndIcon(accessPoint);
            if (endIcon != null) {
                rowBuilder.addEndItem(endIcon, ListBuilder.ICON_IMAGE);
            }
        }
        return rowBuilder;
    }

@@ -218,12 +241,22 @@ public class WifiSlice implements CustomSliceable {
        return null;
    }

    private PendingIntent getAccessPointAction(AccessPoint accessPoint) {
    private SliceAction getCaptivePortalEndAction(AccessPoint accessPoint, CharSequence title) {
        return SliceAction.createDeeplink(
                getAccessPointAction(accessPoint, false /* isCaptivePortal */),
                IconCompat.createWithResource(mContext, R.drawable.ic_settings_accent),
                ListBuilder.ICON_IMAGE, title);
    }

    private PendingIntent getAccessPointAction(AccessPoint accessPoint, boolean isCaptivePortal) {
        final Bundle extras = new Bundle();
        accessPoint.saveWifiState(extras);

        Intent intent;
        if (accessPoint.isActive()) {
        if (isCaptivePortal) {
            intent = new Intent(mContext, ConnectToWifiHandler.class);
            intent.putExtra(ConnectivityManager.EXTRA_NETWORK, mWifiManager.getCurrentNetwork());
        } else if (accessPoint.isActive()) {
            intent = new SubSettingLauncher(mContext)
                    .setTitleRes(R.string.pref_title_network_details)
                    .setDestination(WifiNetworkDetailsFragment.class.getName())
@@ -253,6 +286,12 @@ public class WifiSlice implements CustomSliceable {
                .setSubtitle(title);
    }

    protected boolean isCaptivePortal() {
        final NetworkCapabilities nc = mConnectivityManager.getNetworkCapabilities(
                mWifiManager.getCurrentNetwork());
        return WifiUtils.canSignIntoNetwork(nc);
    }

    /**
     * Update the current wifi status to the boolean value keyed by
     * {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}.
@@ -317,6 +356,12 @@ public class WifiSlice implements CustomSliceable {
    }

    private CharSequence getSummary(AccessPoint accessPoint) {
        if (isCaptivePortal()) {
            final int id = mContext.getResources()
                    .getIdentifier("network_available_sign_in", "string", "android");
            return mContext.getText(id);
        }

        if (accessPoint == null) {
            return getSummary();
        }
Loading