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

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

Merge changes I5455ddda,I629319aa,I30f61ae8

* changes:
  Display summary for connected Passpoint credential APs
  Removed Passpoint Credential AP unconnected summary case
  Added initial OsuProvider support for AccessPoint and WifiTracker
parents 82637f5e 0a3edf0d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -99,6 +99,8 @@
    <string name="connected_via_network_scorer_default">Automatically connected via network rating provider</string>
    <!-- Status message of Wi-Fi when it is connected by Passpoint configuration. [CHAR LIMIT=NONE] -->
    <string name="connected_via_passpoint">Connected via %1$s</string>
    <!-- Status message of Wi-Fi when it is connected by Passpoint configuration. [CHAR LIMIT=NONE] -->
    <string name="ssid_by_passpoint_provider"><xliff:g id="ssid" example="Cafe Wifi">%1$s</xliff:g> by <xliff:g id="passpointProvider" example="Passpoint Provider">%2$s</xliff:g></string>
    <!-- Status message of Wi-Fi when network has matching passpoint credentials. [CHAR LIMIT=NONE] -->
    <string name="available_via_passpoint">Available via %1$s</string>
    <!-- Package name for Settings app-->
+139 −91
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkScoreCache;
import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.os.Bundle;
import android.os.Parcelable;
@@ -182,6 +183,10 @@ public class AccessPoint implements Comparable<AccessPoint> {

    public static final int UNREACHABLE_RSSI = Integer.MIN_VALUE;

    public static final String KEY_PREFIX_AP = "AP:";
    public static final String KEY_PREFIX_FQDN = "FQDN:";
    public static final String KEY_PREFIX_OSU = "OSU:";

    private final Context mContext;

    private String ssid;
@@ -204,9 +209,6 @@ public class AccessPoint implements Comparable<AccessPoint> {
    @Speed private int mSpeed = Speed.NONE;
    private boolean mIsScoredNetworkMetered = false;

    // used to co-relate internal vs returned accesspoint.
    int mId;

    /**
     * Information associated with the {@link PasspointConfiguration}.  Only maintaining
     * the relevant info to preserve spaces.
@@ -215,6 +217,8 @@ public class AccessPoint implements Comparable<AccessPoint> {
    private String mProviderFriendlyName;

    private boolean mIsCarrierAp = false;

    private OsuProvider mOsuProvider;
    /**
     * The EAP type {@link WifiEnterpriseConfig.Eap} associated with this AP if it is a carrier AP.
     */
@@ -280,14 +284,18 @@ public class AccessPoint implements Comparable<AccessPoint> {
        // Calculate required fields
        updateKey();
        updateRssi();

        mId = sLastId.incrementAndGet();
    }

    /**
     * Creates an AccessPoint with only a WifiConfiguration. This is used for the saved networks
     * page.
     *
     * Passpoint Credential AccessPoints should be created with this.
     * Make sure to call setScanResults after constructing with this.
     */
    public AccessPoint(Context context, WifiConfiguration config) {
        mContext = context;
        loadConfig(config);
        mId = sLastId.incrementAndGet();
    }

    /**
@@ -298,7 +306,19 @@ public class AccessPoint implements Comparable<AccessPoint> {
        mContext = context;
        mFqdn = config.getHomeSp().getFqdn();
        mProviderFriendlyName = config.getHomeSp().getFriendlyName();
        mId = sLastId.incrementAndGet();
    }

    /**
     * Initialize an AccessPoint object for a Passpoint OSU Provider.
     * Make sure to call setScanResults after constructing with this.
     */
    public AccessPoint(Context context, OsuProvider provider) {
        mContext = context;
        mOsuProvider = provider;
        mRssi = 1;
        // TODO: This placeholder SSID is here to avoid null pointer exceptions.
        ssid = "<OsuProvider AP SSID goes here>";
        updateKey();
    }

    AccessPoint(Context context, Collection<ScanResult> results) {
@@ -324,8 +344,6 @@ public class AccessPoint implements Comparable<AccessPoint> {
        mIsCarrierAp = firstResult.isCarrierAp;
        mCarrierApEapType = firstResult.carrierApEapType;
        mCarrierName = firstResult.carrierName;

        mId = sLastId.incrementAndGet();
    }

    @VisibleForTesting void loadConfig(WifiConfiguration config) {
@@ -344,14 +362,19 @@ public class AccessPoint implements Comparable<AccessPoint> {
        StringBuilder builder = new StringBuilder();

        if (isPasspoint()) {
            builder.append(mConfig.FQDN);
        } else if (TextUtils.isEmpty(getSsidStr())) {
            builder.append(KEY_PREFIX_FQDN).append(mConfig.FQDN);
        } else if (isOsuProvider()) {
            builder.append(KEY_PREFIX_OSU).append(mOsuProvider.getOsuSsid());
            builder.append(',').append(mOsuProvider.getServerUri());
        } else { // Non-Passpoint AP
            builder.append(KEY_PREFIX_AP);
            if (TextUtils.isEmpty(getSsidStr())) {
                builder.append(getBssid());
            } else {
                builder.append(getSsidStr());
            }

            builder.append(',').append(getSecurity());
        }
        mKey = builder.toString();
    }

@@ -396,8 +419,8 @@ public class AccessPoint implements Comparable<AccessPoint> {
            return difference;
        }

        // Sort by ssid.
        difference = getSsidStr().compareToIgnoreCase(other.getSsidStr());
        // Sort by title.
        difference = getTitle().compareToIgnoreCase(other.getTitle());
        if (difference != 0) {
            return difference;
        }
@@ -595,6 +618,7 @@ public class AccessPoint implements Comparable<AccessPoint> {
    public static String getKey(ScanResult result) {
        StringBuilder builder = new StringBuilder();

        builder.append(KEY_PREFIX_AP);
        if (TextUtils.isEmpty(result.SSID)) {
            builder.append(result.BSSID);
        } else {
@@ -609,14 +633,17 @@ public class AccessPoint implements Comparable<AccessPoint> {
        StringBuilder builder = new StringBuilder();

        if (config.isPasspoint()) {
            builder.append(config.FQDN);
        } else if (TextUtils.isEmpty(config.SSID)) {
            builder.append(KEY_PREFIX_FQDN).append(config.FQDN);
        } else {
            builder.append(KEY_PREFIX_AP);
            if (TextUtils.isEmpty(config.SSID)) {
                builder.append(config.BSSID);
            } else {
                builder.append(removeDoubleQuotes(config.SSID));
            }

            builder.append(',').append(getSecurity(config));
        }

        return builder.toString();
    }

@@ -839,46 +866,45 @@ public class AccessPoint implements Comparable<AccessPoint> {
    public String getTitle() {
        if (isPasspoint()) {
            return mConfig.providerFriendlyName;
        } else if (isOsuProvider()) {
            return mOsuProvider.getFriendlyName();
        } else {
            return getSsidStr();
        }
    }

    public String getSummary() {
        return getSettingsSummary(mConfig);
        return getSettingsSummary();
    }

    public String getSettingsSummary() {
        return getSettingsSummary(mConfig);
    }

    private String getSettingsSummary(WifiConfiguration config) {
        // Update to new summary
        StringBuilder summary = new StringBuilder();

        if (isActive() && config != null && config.isPasspoint()) {
        if (isActive()) {
            if (isPasspoint()) {
                // This is the active connection on passpoint
            summary.append(getSummary(mContext, getDetailedState(),
                    false, config.providerFriendlyName));
        } else if (isActive() && config != null && getDetailedState() == DetailedState.CONNECTED
                summary.append(getSummary(mContext, ssid, getDetailedState(),
                        false, mConfig.providerFriendlyName));
            } else if (mConfig != null && getDetailedState() == DetailedState.CONNECTED
                    && mIsCarrierAp) {
            summary.append(String.format(mContext.getString(R.string.connected_via_carrier), mCarrierName));
        } else if (isActive()) {
                // This is the active connection on a carrier AP
                summary.append(String.format(mContext.getString(R.string.connected_via_carrier),
                        mCarrierName));
            } else {
                // This is the active connection on non-passpoint network
                summary.append(getSummary(mContext, getDetailedState(),
                        mInfo != null && mInfo.isEphemeral()));
        } else if (config != null && config.isPasspoint()
                && config.getNetworkSelectionStatus().isNetworkEnabled()) {
            String format = mContext.getString(R.string.available_via_passpoint);
            summary.append(String.format(format, config.providerFriendlyName));
        } else if (config != null && config.hasNoInternetAccess()) {
            int messageID = config.getNetworkSelectionStatus().isNetworkPermanentlyDisabled()
            }
        } else { // not active
            if (mConfig != null && mConfig.hasNoInternetAccess()) {
                int messageID = mConfig.getNetworkSelectionStatus().isNetworkPermanentlyDisabled()
                        ? R.string.wifi_no_internet_no_reconnect
                        : R.string.wifi_no_internet;
                summary.append(mContext.getString(messageID));
        } else if (config != null && !config.getNetworkSelectionStatus().isNetworkEnabled()) {
            } else if (mConfig != null && !mConfig.getNetworkSelectionStatus().isNetworkEnabled()) {
                WifiConfiguration.NetworkSelectionStatus networkStatus =
                    config.getNetworkSelectionStatus();
                        mConfig.getNetworkSelectionStatus();
                switch (networkStatus.getNetworkSelectionDisableReason()) {
                    case WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE:
                        summary.append(mContext.getString(R.string.wifi_disabled_password_failure));
@@ -894,16 +920,18 @@ public class AccessPoint implements Comparable<AccessPoint> {
                        summary.append(mContext.getString(R.string.wifi_disabled_generic));
                        break;
                }
        } else if (config != null && config.getNetworkSelectionStatus().isNotRecommended()) {
            summary.append(mContext.getString(R.string.wifi_disabled_by_recommendation_provider));
            } else if (mConfig != null && mConfig.getNetworkSelectionStatus().isNotRecommended()) {
                summary.append(mContext.getString(
                        R.string.wifi_disabled_by_recommendation_provider));
            } else if (mIsCarrierAp) {
            summary.append(String.format(mContext.getString(R.string.available_via_carrier), mCarrierName));
                summary.append(String.format(mContext.getString(
                        R.string.available_via_carrier), mCarrierName));
            } else if (!isReachable()) { // Wifi out of range
                summary.append(mContext.getString(R.string.wifi_not_in_range));
            } else { // In range, not disabled.
            if (config != null) { // Is saved network
                if (mConfig != null) { // Is saved network
                    // Last attempt to connect to this failed. Show reason why
                switch (config.recentFailure.getAssociationStatus()) {
                    switch (mConfig.recentFailure.getAssociationStatus()) {
                        case WifiConfiguration.RecentFailure.STATUS_AP_UNABLE_TO_HANDLE_NEW_STA:
                            summary.append(mContext.getString(
                                    R.string.wifi_ap_unable_to_handle_new_sta));
@@ -915,15 +943,18 @@ public class AccessPoint implements Comparable<AccessPoint> {
                    }
                }
            }
        }



        if (isVerboseLoggingEnabled()) {
            summary.append(WifiUtils.buildLoggingSummary(this, config));
            summary.append(WifiUtils.buildLoggingSummary(this, mConfig));
        }

        if (config != null && (WifiUtils.isMeteredOverridden(config) || config.meteredHint)) {
        if (mConfig != null && (WifiUtils.isMeteredOverridden(mConfig) || mConfig.meteredHint)) {
            return mContext.getResources().getString(
                    R.string.preference_summary_default_combination,
                    WifiUtils.getMeteredLabel(mContext, config),
                    WifiUtils.getMeteredLabel(mContext, mConfig),
                    summary.toString());
        }

@@ -975,6 +1006,13 @@ public class AccessPoint implements Comparable<AccessPoint> {
        return mFqdn != null;
    }

    /**
     * Return true if this AccessPoint represents an OSU Provider.
     */
    public boolean isOsuProvider() {
        return mOsuProvider != null;
    }

    /**
     * Return whether the given {@link WifiInfo} is for this access point.
     * If the current AP does not have a network Id then the config is used to
@@ -1065,8 +1103,8 @@ public class AccessPoint implements Comparable<AccessPoint> {
    void setScanResults(Collection<ScanResult> scanResults) {

        // 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()) {
        // Passpoint networks are not bound to a specific SSID/BSSID, so skip this for passpoint.
        if (!isPasspoint() && !isOsuProvider()) {
            String key = getKey();
            for (ScanResult result : scanResults) {
                String scanResultKey = AccessPoint.getKey(result);
@@ -1119,7 +1157,17 @@ public class AccessPoint implements Comparable<AccessPoint> {
        }
    }

    /** Attempt to update the AccessPoint and return true if an update occurred. */
    /**
     * Attempt to update the AccessPoint with the current connection info.
     * This is used to set an AccessPoint to the active one if the connection info matches, or
     * conversely to set an AccessPoint to inactive if the connection info does not match. The RSSI
     * is also updated upon a match. Listeners will be notified if an update occurred.
     *
     * This is called in {@link WifiTracker#updateAccessPoints} as well as in callbacks for handling
     * NETWORK_STATE_CHANGED_ACTION, RSSI_CHANGED_ACTION, and onCapabilitiesChanged in WifiTracker.
     *
     * Returns true if an update occurred.
     */
    public boolean update(
            @Nullable WifiConfiguration config, WifiInfo info, NetworkInfo networkInfo) {

@@ -1246,11 +1294,11 @@ public class AccessPoint implements Comparable<AccessPoint> {

    public static String getSummary(Context context, String ssid, DetailedState state,
            boolean isEphemeral, String passpointProvider) {
        if (state == DetailedState.CONNECTED && ssid == null) {
            if (TextUtils.isEmpty(passpointProvider) == false) {
        if (state == DetailedState.CONNECTED) {
            if (!TextUtils.isEmpty(passpointProvider)) {
                // Special case for connected + passpoint networks.
                String format = context.getString(R.string.connected_via_passpoint);
                return String.format(format, passpointProvider);
                String format = context.getString(R.string.ssid_by_passpoint_provider);
                return String.format(format, ssid, passpointProvider);
            } else if (isEphemeral) {
                // Special case for connected + ephemeral networks.
                final NetworkScoreManager networkScoreManager = context.getSystemService(
+19 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkScoreCache;
import android.net.wifi.WifiNetworkScoreCache.CacheListener;
import android.net.wifi.hotspot2.OsuProvider;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
@@ -584,7 +585,7 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro
                    Map<Integer, List<ScanResult>>> pairing : passpointConfigsAndScans) {
                WifiConfiguration config = pairing.first;

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

                List<ScanResult> homeScans =
@@ -618,6 +619,23 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro
                }
            }

            // Add Passpoint OSU Provider AccessPoints
            // TODO(b/118705403): filter out OSU Providers which we already have credentials from.
            Map<OsuProvider, List<ScanResult>> providersAndScans =
                    mWifiManager.getMatchingOsuProviders(cachedScanResults);
            for (OsuProvider provider : providersAndScans.keySet()) {
                AccessPoint accessPointOsu = new AccessPoint(mContext, provider);
                // TODO(b/118705403): accessPointOsu.setScanResults(Matching ScanResult with best
                // RSSI)
                // TODO(b/118705403): Figure out if we would need to update an OSU AP (this will be
                // used if we need to display it at the top of the picker as the "active" AP).
                // Otherwise, OSU APs should ignore attempts to update the active connection
                // info.
                // accessPointOsu.update(connectionConfig, mLastInfo, mLastNetworkInfo);
                accessPoints.add(accessPointOsu);
            }


            // If there were no scan results, create an AP for the currently connected network (if
            // it exists).
            if (accessPoints.isEmpty() && connectionConfig != null) {