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
This commit is contained in:
@@ -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-->
|
||||
|
||||
@@ -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(getBssid());
|
||||
} else {
|
||||
builder.append(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());
|
||||
}
|
||||
|
||||
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(config.BSSID);
|
||||
builder.append(KEY_PREFIX_FQDN).append(config.FQDN);
|
||||
} else {
|
||||
builder.append(removeDoubleQuotes(config.SSID));
|
||||
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));
|
||||
}
|
||||
|
||||
builder.append(',').append(getSecurity(config));
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@@ -839,91 +866,95 @@ 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()) {
|
||||
// This is the active connection on passpoint
|
||||
summary.append(getSummary(mContext, getDetailedState(),
|
||||
false, config.providerFriendlyName));
|
||||
} else if (isActive() && config != 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 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()
|
||||
? R.string.wifi_no_internet_no_reconnect
|
||||
: R.string.wifi_no_internet;
|
||||
summary.append(mContext.getString(messageID));
|
||||
} else if (config != null && !config.getNetworkSelectionStatus().isNetworkEnabled()) {
|
||||
WifiConfiguration.NetworkSelectionStatus networkStatus =
|
||||
config.getNetworkSelectionStatus();
|
||||
switch (networkStatus.getNetworkSelectionDisableReason()) {
|
||||
case WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE:
|
||||
summary.append(mContext.getString(R.string.wifi_disabled_password_failure));
|
||||
break;
|
||||
case WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD:
|
||||
summary.append(mContext.getString(R.string.wifi_check_password_try_again));
|
||||
break;
|
||||
case WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE:
|
||||
case WifiConfiguration.NetworkSelectionStatus.DISABLED_DNS_FAILURE:
|
||||
summary.append(mContext.getString(R.string.wifi_disabled_network_failure));
|
||||
break;
|
||||
case WifiConfiguration.NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION:
|
||||
summary.append(mContext.getString(R.string.wifi_disabled_generic));
|
||||
break;
|
||||
if (isActive()) {
|
||||
if (isPasspoint()) {
|
||||
// This is the active connection on passpoint
|
||||
summary.append(getSummary(mContext, ssid, getDetailedState(),
|
||||
false, mConfig.providerFriendlyName));
|
||||
} else if (mConfig != null && getDetailedState() == DetailedState.CONNECTED
|
||||
&& mIsCarrierAp) {
|
||||
// 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.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));
|
||||
} 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
|
||||
// Last attempt to connect to this failed. Show reason why
|
||||
switch (config.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));
|
||||
} 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 (mConfig != null && !mConfig.getNetworkSelectionStatus().isNetworkEnabled()) {
|
||||
WifiConfiguration.NetworkSelectionStatus networkStatus =
|
||||
mConfig.getNetworkSelectionStatus();
|
||||
switch (networkStatus.getNetworkSelectionDisableReason()) {
|
||||
case WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE:
|
||||
summary.append(mContext.getString(R.string.wifi_disabled_password_failure));
|
||||
break;
|
||||
default:
|
||||
// "Saved"
|
||||
summary.append(mContext.getString(R.string.wifi_remembered));
|
||||
case WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD:
|
||||
summary.append(mContext.getString(R.string.wifi_check_password_try_again));
|
||||
break;
|
||||
case WifiConfiguration.NetworkSelectionStatus.DISABLED_DHCP_FAILURE:
|
||||
case WifiConfiguration.NetworkSelectionStatus.DISABLED_DNS_FAILURE:
|
||||
summary.append(mContext.getString(R.string.wifi_disabled_network_failure));
|
||||
break;
|
||||
case WifiConfiguration.NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION:
|
||||
summary.append(mContext.getString(R.string.wifi_disabled_generic));
|
||||
break;
|
||||
}
|
||||
} 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));
|
||||
} else if (!isReachable()) { // Wifi out of range
|
||||
summary.append(mContext.getString(R.string.wifi_not_in_range));
|
||||
} else { // In range, not disabled.
|
||||
if (mConfig != null) { // Is saved network
|
||||
// Last attempt to connect to this failed. Show reason why
|
||||
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));
|
||||
break;
|
||||
default:
|
||||
// "Saved"
|
||||
summary.append(mContext.getString(R.string.wifi_remembered));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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(
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user