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

Commit 089c5431 authored by Quang Luong's avatar Quang Luong Committed by Android (Google) Code Review
Browse files

Merge "Connect to Passpoint network immediately after OSU provisioning"

parents 03dda730 7cfa5275
Loading
Loading
Loading
Loading
+53 −3
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;

import androidx.annotation.NonNull;

@@ -65,8 +66,10 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
@@ -197,6 +200,9 @@ public class AccessPoint implements Comparable<AccessPoint> {

    private final Context mContext;

    private WifiManager mWifiManager;
    private WifiManager.ActionListener mConnectListener;

    private String ssid;
    private String bssid;
    private int security;
@@ -1068,8 +1074,10 @@ public class AccessPoint implements Comparable<AccessPoint> {
    /**
     * Starts the OSU Provisioning flow.
     */
    public void startOsuProvisioning() {
        mContext.getSystemService(WifiManager.class).startSubscriptionProvisioning(
    public void startOsuProvisioning(@Nullable WifiManager.ActionListener connectListener) {
        mConnectListener = connectListener;

        getWifiManager().startSubscriptionProvisioning(
                mOsuProvider,
                mContext.getMainExecutor(),
                new AccessPointProvisioningCallback()
@@ -1539,12 +1547,20 @@ public class AccessPoint implements Comparable<AccessPoint> {
        return string;
    }

    private WifiManager getWifiManager() {
        if (mWifiManager == null) {
            mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
        }
        return mWifiManager;
    }

    /**
     * Callbacks relaying changes to the AccessPoint representation.
     *
     * <p>All methods are invoked on the Main Thread.
     */
    public interface AccessPointListener {

        /**
         * Indicates a change to the externally visible state of the AccessPoint trigger by an
         * update of ScanResults, saved configuration state, connection state, or score
@@ -1561,7 +1577,6 @@ public class AccessPoint implements Comparable<AccessPoint> {
         *                    changed
         */
        @MainThread void onAccessPointChanged(AccessPoint accessPoint);

        /**
         * Indicates the "wifi pie signal level" has changed, retrieved via calls to
         * {@link AccessPoint#getLevel()}.
@@ -1643,11 +1658,46 @@ public class AccessPoint implements Comparable<AccessPoint> {
            mOsuProvisioningComplete = true;
            mOsuFailure = null;
            mOsuStatus = null;

            ThreadUtils.postOnMainThread(() -> {
                if (mAccessPointListener != null) {
                    mAccessPointListener.onAccessPointChanged(AccessPoint.this);
                }
            });

            // Connect to the freshly provisioned network.
            WifiManager wifiManager = getWifiManager();

            PasspointConfiguration passpointConfig = wifiManager
                    .getMatchingPasspointConfigsForOsuProviders(Collections.singleton(mOsuProvider))
                    .get(mOsuProvider);
            if (passpointConfig == null) {
                Log.e(TAG, "Missing PasspointConfiguration for newly provisioned network!");
                if (mConnectListener != null) {
                    mConnectListener.onFailure(0);
                }
                return;
            }

            String fqdn = passpointConfig.getHomeSp().getFqdn();
            for (Pair<WifiConfiguration, Map<Integer, List<ScanResult>>> pairing :
                    wifiManager.getAllMatchingWifiConfigs(wifiManager.getScanResults())) {
                WifiConfiguration config = pairing.first;
                if (TextUtils.equals(config.FQDN, fqdn)) {
                    List<ScanResult> homeScans =
                            pairing.second.get(WifiManager.PASSPOINT_HOME_NETWORK);
                    List<ScanResult> roamingScans =
                            pairing.second.get(WifiManager.PASSPOINT_ROAMING_NETWORK);

                    AccessPoint connectionAp =
                            new AccessPoint(mContext, config, homeScans, roamingScans);
                    wifiManager.connect(connectionAp.getConfig(), mConnectListener);
                    return;
                }
            }
            if (mConnectListener != null) {
                mConnectListener.onFailure(0);
            }
        }
    }
}
+87 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkScoreCache;
import android.net.wifi.WifiSsid;
import android.net.wifi.hotspot2.OsuProvider;
@@ -53,6 +54,7 @@ import android.os.SystemClock;
import android.text.SpannableString;
import android.text.format.DateUtils;
import android.util.ArraySet;
import android.util.Pair;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -72,6 +74,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
@@ -95,9 +98,12 @@ public class AccessPointTest {

    private Context mContext;
    private WifiInfo mWifiInfo;
    @Mock private Context mMockContext;
    @Mock private WifiManager mMockWifiManager;
    @Mock private RssiCurve mockBadgeCurve;
    @Mock private WifiNetworkScoreCache mockWifiNetworkScoreCache;
    @Mock private AccessPoint.AccessPointListener mMockAccessPointListener;
    @Mock private WifiManager.ActionListener mMockConnectListener;
    private static final int NETWORK_ID = 123;
    private static final int DEFAULT_RSSI = -55;

@@ -1360,6 +1366,9 @@ public class AccessPointTest {
                .isEqualTo(mContext.getString(R.string.tap_to_sign_up));
    }

    /**
     * Verifies that the summary of an OSU entry updates based on provisioning status.
     */
    @Test
    public void testOsuAccessPointSummary_showsProvisioningUpdates() {
        AccessPoint osuAccessPoint = new AccessPoint(mContext, createOsuProvider(),
@@ -1411,4 +1420,82 @@ public class AccessPointTest {
        assertThat(osuAccessPoint.getSummary())
                .isEqualTo(mContext.getString(R.string.osu_sign_up_complete));
    }

    /**
     * Verifies that after provisioning through an OSU provider, we connect to the freshly
     * provisioned network.
     */
    @Test
    public void testOsuAccessPoint_connectsAfterProvisioning() {
        // Set up mock for WifiManager.getAllMatchingWifiConfigs
        WifiConfiguration config = new WifiConfiguration();
        config.FQDN = "fqdn";
        Map<Integer, List<ScanResult>> scanMapping = new HashMap<>();
        scanMapping.put(WifiManager.PASSPOINT_HOME_NETWORK, mScanResults);
        Pair<WifiConfiguration, Map<Integer, List<ScanResult>>> configMapPair =
                new Pair<>(config, scanMapping);
        List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> matchingWifiConfig =
                new ArrayList<>();
        matchingWifiConfig.add(configMapPair);
        when(mMockWifiManager.getAllMatchingWifiConfigs(any())).thenReturn(matchingWifiConfig);

        // Set up mock for WifiManager.getMatchingPasspointConfigsForOsuProviders
        OsuProvider provider = createOsuProvider();
        PasspointConfiguration passpointConfig = new PasspointConfiguration();
        HomeSp homeSp = new HomeSp();
        homeSp.setFqdn("fqdn");
        homeSp.setFriendlyName("Test Provider");
        passpointConfig.setHomeSp(homeSp);
        Map<OsuProvider, PasspointConfiguration> osuProviderConfigMap = new HashMap<>();
        osuProviderConfigMap.put(provider, passpointConfig);
        when(mMockWifiManager
                .getMatchingPasspointConfigsForOsuProviders(Collections.singleton(provider)))
                .thenReturn(osuProviderConfigMap);

        when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager);

        AccessPoint osuAccessPoint = new AccessPoint(mMockContext, provider, mScanResults);
        osuAccessPoint.setListener(mMockAccessPointListener);

        AccessPoint.AccessPointProvisioningCallback provisioningCallback =
                osuAccessPoint.new AccessPointProvisioningCallback();
        provisioningCallback.onProvisioningComplete();

        verify(mMockWifiManager).connect(any(), any());
    }

    /**
     * Verifies that after provisioning through an OSU provider, we call the connect listener's
     * onFailure() method if we cannot find the network we just provisioned.
     */
    @Test
    public void testOsuAccessPoint_noMatchingConfigsAfterProvisioning_callsOnFailure() {
        // Set up mock for WifiManager.getAllMatchingWifiConfigs
        when(mMockWifiManager.getAllMatchingWifiConfigs(any())).thenReturn(new ArrayList<>());

        // Set up mock for WifiManager.getMatchingPasspointConfigsForOsuProviders
        OsuProvider provider = createOsuProvider();
        PasspointConfiguration passpointConfig = new PasspointConfiguration();
        HomeSp homeSp = new HomeSp();
        homeSp.setFqdn("fqdn");
        homeSp.setFriendlyName("Test Provider");
        passpointConfig.setHomeSp(homeSp);
        Map<OsuProvider, PasspointConfiguration> osuProviderConfigMap = new HashMap<>();
        osuProviderConfigMap.put(provider, passpointConfig);
        when(mMockWifiManager
                .getMatchingPasspointConfigsForOsuProviders(Collections.singleton(provider)))
                .thenReturn(osuProviderConfigMap);

        when(mMockContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mMockWifiManager);

        AccessPoint osuAccessPoint = new AccessPoint(mMockContext, provider, mScanResults);
        osuAccessPoint.setListener(mMockAccessPointListener);
        osuAccessPoint.startOsuProvisioning(mMockConnectListener);

        AccessPoint.AccessPointProvisioningCallback provisioningCallback =
                osuAccessPoint.new AccessPointProvisioningCallback();
        provisioningCallback.onProvisioningComplete();

        verify(mMockConnectListener).onFailure(anyInt());
    }
}