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

Commit 7054e925 authored by Quang Luong's avatar Quang Luong
Browse files

Added Passpoint R1 AccessPoints to show up in wifi picker.

The wifi picker in WifiSettings should now display entries for
Passpoint credential networks by their provider friendly name.
The RSSI displayed is the max RSSI from the matching scan results
of the passpoint network, and tapping on the entry will connect to
the matching AP with the highest RSSI.

Test: manual, logs and visual check
Bug: 118705403
Change-Id: I256f0580ff1cf34dad0d808abfa980e0e39fa14c
parent 43c2670c
Loading
Loading
Loading
Loading
+36 −14
Original line number Diff line number Diff line
@@ -332,9 +332,9 @@ public class AccessPoint implements Comparable<AccessPoint> {
        ssid = (config.SSID == null ? "" : removeDoubleQuotes(config.SSID));
        bssid = config.BSSID;
        security = getSecurity(config);
        updateKey();
        networkId = config.networkId;
        mConfig = config;
        updateKey();
    }

    /** Updates {@link #mKey} and should only called upon object creation/initialization. */
@@ -343,7 +343,9 @@ public class AccessPoint implements Comparable<AccessPoint> {

        StringBuilder builder = new StringBuilder();

        if (TextUtils.isEmpty(getSsidStr())) {
        if (isPasspoint()) {
            builder.append(mConfig.FQDN);
        } else if (TextUtils.isEmpty(getSsidStr())) {
            builder.append(getBssid());
        } else {
            builder.append(getSsidStr());
@@ -606,7 +608,9 @@ public class AccessPoint implements Comparable<AccessPoint> {
    public static String getKey(WifiConfiguration config) {
        StringBuilder builder = new StringBuilder();

        if (TextUtils.isEmpty(config.SSID)) {
        if (config.isPasspoint()) {
            builder.append(config.FQDN);
        } else if (TextUtils.isEmpty(config.SSID)) {
            builder.append(config.BSSID);
        } else {
            builder.append(removeDoubleQuotes(config.SSID));
@@ -621,9 +625,10 @@ public class AccessPoint implements Comparable<AccessPoint> {
    }

    public boolean matches(WifiConfiguration config) {
        if (config.isPasspoint() && mConfig != null && mConfig.isPasspoint()) {
            return ssid.equals(removeDoubleQuotes(config.SSID)) && config.FQDN.equals(mConfig.FQDN);
        if (config.isPasspoint()) {
            return (isPasspoint() && config.FQDN.equals(mConfig.FQDN));
        } else {
            // Normal non-Passpoint network
            return ssid.equals(removeDoubleQuotes(config.SSID))
                    && security == getSecurity(config)
                    && (mConfig == null || mConfig.shared == config.shared);
@@ -828,6 +833,17 @@ public class AccessPoint implements Comparable<AccessPoint> {
        return "";
    }

    /**
     * Returns the display title for the AccessPoint, such as for an AccessPointPreference's title.
     */
    public String getTitle() {
        if (isPasspoint()) {
            return mConfig.providerFriendlyName;
        } else {
            return getSsidStr();
        }
    }

    public String getSummary() {
        return getSettingsSummary(mConfig);
    }
@@ -1048,17 +1064,20 @@ public class AccessPoint implements Comparable<AccessPoint> {
     */
    void setScanResults(Collection<ScanResult> scanResults) {

        // Validate scan results are for current AP only
        // Validate scan results are for current AP only by matching SSID/BSSID
        // Passpoint R1 networks are not bound to a specific SSID/BSSID, so skip this for passpoint.
        if (!isPasspoint()) {
            String key = getKey();
            for (ScanResult result : scanResults) {
                String scanResultKey = AccessPoint.getKey(result);
                if (!mKey.equals(scanResultKey)) {
                    throw new IllegalArgumentException(
                        String.format("ScanResult %s\nkey of %s did not match current AP key %s",
                            String.format(
                                    "ScanResult %s\nkey of %s did not match current AP key %s",
                                    result, scanResultKey, key));
                }
            }

        }

        int oldLevel = getLevel();
        mScanResults.clear();
@@ -1149,6 +1168,9 @@ public class AccessPoint implements Comparable<AccessPoint> {

    void update(@Nullable WifiConfiguration config) {
        mConfig = config;
        if (mConfig != null) {
            ssid = removeDoubleQuotes(mConfig.SSID);
        }
        networkId = config != null ? config.networkId : WifiConfiguration.INVALID_NETWORK_ID;
        ThreadUtils.postOnMainThread(() -> {
            if (mAccessPointListener != null) {
+1 −1
Original line number Diff line number Diff line
@@ -266,7 +266,7 @@ public class AccessPointPreference extends Preference {
        if (savedNetworks) {
            preference.setTitle(ap.getConfigName());
        } else {
            preference.setTitle(ap.getSsidStr());
            preference.setTitle(ap.getTitle());
        }
    }

+45 −1
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;
import android.widget.Toast;

import androidx.annotation.GuardedBy;
@@ -573,9 +574,52 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro
                accessPoints.add(accessPoint);
            }

            List<ScanResult> cachedScanResults = new ArrayList<>(mScanResultCache.values());

            // Add a unique Passpoint R1 AccessPoint for each Passpoint profile's FQDN.
            List<Pair<WifiConfiguration, Map<Integer, List<ScanResult>>>> passpointConfigsAndScans =
                    mWifiManager.getAllMatchingWifiConfigs(cachedScanResults);
            Set<String> seenFQDNs = new ArraySet<>();
            for (Pair<WifiConfiguration,
                    Map<Integer, List<ScanResult>>> pairing : passpointConfigsAndScans) {
                WifiConfiguration config = pairing.first;

                // TODO: Prioritize home networks before roaming networks
                List<ScanResult> scanResults = new ArrayList<>();

                List<ScanResult> homeScans =
                        pairing.second.get(WifiManager.PASSPOINT_HOME_NETWORK);
                List<ScanResult> roamingScans =
                        pairing.second.get(WifiManager.PASSPOINT_ROAMING_NETWORK);

                if (homeScans == null) {
                    homeScans = new ArrayList<>();
                }
                if (roamingScans == null) {
                    roamingScans = new ArrayList<>();
                }

                scanResults.addAll(homeScans);
                scanResults.addAll(roamingScans);

                if (seenFQDNs.add(config.FQDN)) {
                    int bestRssi = Integer.MIN_VALUE;
                    for (ScanResult result : scanResults) {
                        if (result.level >= bestRssi) {
                            bestRssi = result.level;
                            config.SSID = AccessPoint.convertToQuotedString(result.SSID);
                        }
                    }

                    AccessPoint accessPoint = new AccessPoint(mContext, config);
                    accessPoint.setScanResults(scanResults);
                    accessPoint.update(connectionConfig, mLastInfo, mLastNetworkInfo);
                    accessPoints.add(accessPoint);
                }
            }

            // If there were no scan results, create an AP for the currently connected network (if
            // it exists).
            // TODO(b/b/73076869): Add support for passpoint (ephemeral) networks
            if (accessPoints.isEmpty() && connectionConfig != null) {
                AccessPoint activeAp = new AccessPoint(mContext, connectionConfig);
                activeAp.update(connectionConfig, mLastInfo, mLastNetworkInfo);