From 549f83b742b362ee65c4550d06e9f21ecad04ffd Mon Sep 17 00:00:00 2001 From: Quang Luong Date: Thu, 23 Apr 2020 21:39:03 -0700 Subject: [WifiTrackerLib] Add speed label to network summary Adds speed label (badging) to the network summary, indicating the network speed based on an rssi curve. Test: atest StandardWifiEntryTest, atest PasspointWifiEntryTest Bug: 152568815 Change-Id: I9c193aa3be0fd684312dad2dd51bb011d0db78c3 --- .../android/wifitrackerlib/BaseWifiTracker.java | 45 +++++-- .../com/android/wifitrackerlib/OsuWifiEntry.java | 20 ++-- .../PasspointNetworkDetailsTracker.java | 12 +- .../android/wifitrackerlib/PasspointWifiEntry.java | 65 ++++++---- .../wifitrackerlib/SavedNetworkTracker.java | 17 ++- .../StandardNetworkDetailsTracker.java | 8 +- .../android/wifitrackerlib/StandardWifiEntry.java | 49 +++++--- .../src/com/android/wifitrackerlib/Utils.java | 74 +++++++++++- .../src/com/android/wifitrackerlib/WifiEntry.java | 35 +++++- .../android/wifitrackerlib/WifiPickerTracker.java | 35 ++++-- .../wifitrackerlib/PasspointWifiEntryTest.java | 97 ++++++++++++++- .../wifitrackerlib/StandardWifiEntryTest.java | 132 +++++++++++++++------ .../src/com/android/wifitrackerlib/UtilsTest.java | 12 +- 13 files changed, 485 insertions(+), 116 deletions(-) diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java index bc551c20d..2f5b56eea 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/BaseWifiTracker.java @@ -18,6 +18,8 @@ package com.android.wifitrackerlib; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; +import static java.util.stream.Collectors.toList; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -26,9 +28,12 @@ import android.net.ConnectivityManager; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; +import android.net.NetworkKey; import android.net.NetworkRequest; import android.net.NetworkScoreManager; +import android.net.ScoredNetwork; import android.net.wifi.WifiManager; +import android.net.wifi.WifiNetworkScoreCache; import android.os.Handler; import android.os.Looper; import android.util.Log; @@ -43,6 +48,9 @@ import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.OnLifecycleEvent; import java.time.Clock; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * Base class for WifiTracker functionality. @@ -79,13 +87,6 @@ public class BaseWifiTracker implements LifecycleObserver { } private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { - /** - * TODO (b/70983952): Add the rest of the broadcast handling. - * WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION); - * WifiManager.ACTION_LINK_CONFIGURATION_CHANGED); - * WifiManager.NETWORK_STATE_CHANGED_ACTION); - * WifiManager.RSSI_CHANGED_ACTION); - */ @Override @WorkerThread public void onReceive(Context context, Intent intent) { @@ -104,6 +105,10 @@ public class BaseWifiTracker implements LifecycleObserver { notifyOnWifiStateChanged(); handleWifiStateChangedAction(); } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) { + mNetworkScoreManager.requestScores(mWifiManager.getScanResults().stream() + .map(NetworkKey::createFromScanResult) + .filter(mRequestedScoreKeys::add) + .collect(toList())); handleScanResultsAvailableAction(intent); } else if (WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action)) { handleConfiguredNetworksChangedAction(intent); @@ -126,6 +131,8 @@ public class BaseWifiTracker implements LifecycleObserver { protected final long mMaxScanAgeMillis; protected final long mScanIntervalMillis; protected final ScanResultUpdater mScanResultUpdater; + protected final WifiNetworkScoreCache mWifiNetworkScoreCache; + private final Set mRequestedScoreKeys = new HashSet<>(); // Network request for listening on changes to Wifi link properties and network capabilities // such as captive portal availability. @@ -185,6 +192,13 @@ public class BaseWifiTracker implements LifecycleObserver { mScanResultUpdater = new ScanResultUpdater(clock, maxScanAgeMillis + scanIntervalMillis); + mWifiNetworkScoreCache = new WifiNetworkScoreCache(mContext, + new WifiNetworkScoreCache.CacheListener(mWorkerHandler) { + @Override + public void networkCacheUpdated(List networks) { + handleNetworkScoreCacheUpdated(); + } + }); mScanner = new BaseWifiTracker.Scanner(workerHandler.getLooper()); sVerboseLogging = mWifiManager.isVerboseLoggingEnabled(); } @@ -195,7 +209,6 @@ public class BaseWifiTracker implements LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_START) @MainThread public void onStart() { - // TODO (b/70983952): Register score cache and receivers for network callbacks. IntentFilter filter = new IntentFilter(); filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); @@ -206,6 +219,10 @@ public class BaseWifiTracker implements LifecycleObserver { /* broadcastPermission */ null, mWorkerHandler); mConnectivityManager.registerNetworkCallback(mNetworkRequest, mNetworkCallback, mWorkerHandler); + mNetworkScoreManager.registerNetworkScoreCache( + NetworkKey.TYPE_WIFI, + mWifiNetworkScoreCache, + NetworkScoreManager.SCORE_FILTER_SCAN_RESULTS); if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) { mScanner.start(); } else { @@ -220,10 +237,12 @@ public class BaseWifiTracker implements LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_STOP) @MainThread public void onStop() { - // TODO (b/70983952): Unregister score cache and receivers for network callbacks. mScanner.stop(); mContext.unregisterReceiver(mBroadcastReceiver); mConnectivityManager.unregisterNetworkCallback(mNetworkCallback); + mNetworkScoreManager.unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI, + mWifiNetworkScoreCache); + mWorkerHandler.post(mRequestedScoreKeys::clear); } /** @@ -305,6 +324,14 @@ public class BaseWifiTracker implements LifecycleObserver { // Do nothing. } + /** + * Handle updates to the Wifi network score cache, which is stored in mWifiNetworkScoreCache + */ + @WorkerThread + protected void handleNetworkScoreCacheUpdated() { + // Do nothing. + } + /** * Scanner to handle starting scans every SCAN_INTERVAL_MILLIS */ diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java index 55709d1be..16e55fb96 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/OsuWifiEntry.java @@ -28,6 +28,7 @@ import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; 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.net.wifi.hotspot2.ProvisioningCallback; @@ -61,16 +62,15 @@ class OsuWifiEntry extends WifiEntry { @NonNull private OsuProvider mOsuProvider; private String mOsuStatusString; - private int mLevel = WIFI_LEVEL_UNREACHABLE; - /** * Create n OsuWifiEntry with the associated OsuProvider */ OsuWifiEntry(@NonNull Context context, @NonNull Handler callbackHandler, @NonNull OsuProvider osuProvider, @NonNull WifiManager wifiManager, + @NonNull WifiNetworkScoreCache scoreCache, boolean forSavedNetworksPage) throws IllegalArgumentException { - super(callbackHandler, wifiManager, forSavedNetworksPage); + super(callbackHandler, wifiManager, scoreCache, forSavedNetworksPage); checkNotNull(osuProvider, "Cannot construct with null osuProvider!"); @@ -96,11 +96,6 @@ class OsuWifiEntry extends WifiEntry { ? mOsuStatusString : mContext.getString(R.string.tap_to_sign_up); } - @Override - public int getLevel() { - return mLevel; - } - @Override public String getSsid() { // TODO(b/70983952): Fill this method in in case we need the SSID for verbose logging @@ -280,12 +275,11 @@ class OsuWifiEntry extends WifiEntry { } final ScanResult bestScanResult = getBestScanResultByLevel(scanResults); - if (bestScanResult == null) { - mLevel = WIFI_LEVEL_UNREACHABLE; - } else { - mLevel = mWifiManager.calculateSignalLevel(bestScanResult.level); + if (getConnectedState() == CONNECTED_STATE_DISCONNECTED) { + mLevel = bestScanResult != null + ? mWifiManager.calculateSignalLevel(bestScanResult.level) + : WIFI_LEVEL_UNREACHABLE; } - notifyOnUpdated(); } diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointNetworkDetailsTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointNetworkDetailsTracker.java index 21a25ec52..00c786fac 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointNetworkDetailsTracker.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointNetworkDetailsTracker.java @@ -77,7 +77,8 @@ class PasspointNetworkDetailsTracker extends NetworkDetailsTracker { .findAny(); if (optionalPasspointConfig.isPresent()) { mChosenEntry = new PasspointWifiEntry(mContext, mMainHandler, - optionalPasspointConfig.get(), mWifiManager, false /* forSavedNetworksPage */); + optionalPasspointConfig.get(), mWifiManager, mWifiNetworkScoreCache, + false /* forSavedNetworksPage */); } else { Optional optionalWifiConfig = mWifiManager.getPrivilegedConfiguredNetworks() @@ -88,7 +89,8 @@ class PasspointNetworkDetailsTracker extends NetworkDetailsTracker { .findAny(); if (optionalWifiConfig.isPresent()) { mChosenEntry = new PasspointWifiEntry(mContext, mMainHandler, - optionalWifiConfig.get(), mWifiManager, false /* forSavedNetworksPage */); + optionalWifiConfig.get(), mWifiManager, mWifiNetworkScoreCache, + false /* forSavedNetworksPage */); } else { throw new IllegalArgumentException( "Cannot find config for given PasspointWifiEntry key!"); @@ -156,6 +158,12 @@ class PasspointNetworkDetailsTracker extends NetworkDetailsTracker { } } + @WorkerThread + @Override + protected void handleNetworkScoreCacheUpdated() { + mChosenEntry.onScoreCacheUpdated(); + } + @WorkerThread private void updatePasspointWifiEntryScans(@NonNull List scanResults) { checkNotNull(scanResults, "Scan Result list should not be null!"); diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java index 9b923fa07..350580250 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java @@ -23,6 +23,7 @@ import static androidx.core.util.Preconditions.checkNotNull; import static com.android.wifitrackerlib.Utils.getAppLabel; import static com.android.wifitrackerlib.Utils.getAppLabelForWifiConfiguration; import static com.android.wifitrackerlib.Utils.getAutoConnectDescription; +import static com.android.wifitrackerlib.Utils.getAverageSpeedFromScanResults; import static com.android.wifitrackerlib.Utils.getBestScanResultByLevel; import static com.android.wifitrackerlib.Utils.getCarrierNameForSubId; import static com.android.wifitrackerlib.Utils.getCurrentNetworkCapabilitiesInformation; @@ -32,6 +33,7 @@ import static com.android.wifitrackerlib.Utils.getMeteredDescription; import static com.android.wifitrackerlib.Utils.getNetworkDetailedState; import static com.android.wifitrackerlib.Utils.getSecurityTypeFromWifiConfiguration; import static com.android.wifitrackerlib.Utils.getSpeedDescription; +import static com.android.wifitrackerlib.Utils.getSpeedFromWifiInfo; import static com.android.wifitrackerlib.Utils.getSubIdForConfig; import static com.android.wifitrackerlib.Utils.getVerboseLoggingDescription; @@ -41,6 +43,7 @@ import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; +import android.net.wifi.WifiNetworkScoreCache; import android.net.wifi.hotspot2.PasspointConfiguration; import android.os.Handler; import android.text.TextUtils; @@ -80,7 +83,6 @@ public class PasspointWifiEntry extends WifiEntry { private @Security int mSecurity = SECURITY_EAP; private boolean mIsRoaming = false; - private int mLevel = WIFI_LEVEL_UNREACHABLE; protected long mSubscriptionExpirationTimeInMillis; // PasspointConfiguration#setMeteredOverride(int meteredOverride) is a hide API and we can't @@ -96,8 +98,9 @@ public class PasspointWifiEntry extends WifiEntry { PasspointWifiEntry(@NonNull Context context, @NonNull Handler callbackHandler, @NonNull PasspointConfiguration passpointConfig, @NonNull WifiManager wifiManager, + @NonNull WifiNetworkScoreCache scoreCache, boolean forSavedNetworksPage) throws IllegalArgumentException { - super(callbackHandler, wifiManager, forSavedNetworksPage); + super(callbackHandler, wifiManager, scoreCache, forSavedNetworksPage); checkNotNull(passpointConfig, "Cannot construct with null PasspointConfiguration!"); @@ -119,8 +122,9 @@ public class PasspointWifiEntry extends WifiEntry { PasspointWifiEntry(@NonNull Context context, @NonNull Handler callbackHandler, @NonNull WifiConfiguration wifiConfig, @NonNull WifiManager wifiManager, + @NonNull WifiNetworkScoreCache scoreCache, boolean forSavedNetworksPage) throws IllegalArgumentException { - super(callbackHandler, wifiManager, forSavedNetworksPage); + super(callbackHandler, wifiManager, scoreCache, forSavedNetworksPage); checkNotNull(wifiConfig, "Cannot construct with null PasspointConfiguration!"); if (!wifiConfig.isPasspoint()) { @@ -152,12 +156,6 @@ public class PasspointWifiEntry extends WifiEntry { StringJoiner sj = new StringJoiner(mContext.getString(R.string.summary_separator)); - // TODO(b/70983952): Check if it's necessary to add speend information here. - String speedDescription = getSpeedDescription(mContext, this); - if (!TextUtils.isEmpty(speedDescription)) { - sj.add(speedDescription); - } - if (getConnectedState() == CONNECTED_STATE_DISCONNECTED) { String disconnectDescription = getDisconnectedStateDescription(mContext, this); if (TextUtils.isEmpty(disconnectDescription)) { @@ -184,6 +182,11 @@ public class PasspointWifiEntry extends WifiEntry { } } + String speedDescription = getSpeedDescription(mContext, this); + if (!TextUtils.isEmpty(speedDescription)) { + sj.add(speedDescription); + } + String autoConnectDescription = getAutoConnectDescription(mContext, this); if (!TextUtils.isEmpty(autoConnectDescription)) { sj.add(autoConnectDescription); @@ -233,13 +236,12 @@ public class PasspointWifiEntry extends WifiEntry { ? getImsiProtectionDescription(mContext, mWifiConfig) : ""; } - @Override - public int getLevel() { - return mLevel; - } - @Override public String getSsid() { + if (mWifiInfo != null) { + return sanitizeSsid(mWifiInfo.getSSID()); + } + return mWifiConfig != null ? sanitizeSsid(mWifiConfig.SSID) : null; } @@ -511,23 +513,46 @@ public class PasspointWifiEntry extends WifiEntry { } if (mWifiConfig != null) { mSecurity = getSecurityTypeFromWifiConfiguration(wifiConfig); + List currentScanResults = new ArrayList<>(); ScanResult bestScanResult = null; if (homeScanResults != null && !homeScanResults.isEmpty()) { - bestScanResult = getBestScanResultByLevel(homeScanResults); + currentScanResults.addAll(homeScanResults); } else if (roamingScanResults != null && !roamingScanResults.isEmpty()) { + currentScanResults.addAll(roamingScanResults); mIsRoaming = true; - bestScanResult = getBestScanResultByLevel(roamingScanResults); } - if (bestScanResult == null) { - mLevel = WIFI_LEVEL_UNREACHABLE; - } else { + bestScanResult = getBestScanResultByLevel(currentScanResults); + if (bestScanResult != null) { mWifiConfig.SSID = "\"" + bestScanResult.SSID + "\""; - mLevel = mWifiManager.calculateSignalLevel(bestScanResult.level); + } + if (getConnectedState() == CONNECTED_STATE_DISCONNECTED) { + mLevel = bestScanResult != null + ? mWifiManager.calculateSignalLevel(bestScanResult.level) + : WIFI_LEVEL_UNREACHABLE; + // Average speed is used to prevent speed label flickering from multiple APs. + mSpeed = getAverageSpeedFromScanResults(mScoreCache, currentScanResults); } } else { mLevel = WIFI_LEVEL_UNREACHABLE; } + notifyOnUpdated(); + } + @WorkerThread + void onScoreCacheUpdated() { + if (mWifiInfo != null) { + mSpeed = getSpeedFromWifiInfo(mScoreCache, mWifiInfo); + } else { + synchronized (mLock) { + // Average speed is used to prevent speed label flickering from multiple APs. + if (!mCurrentHomeScanResults.isEmpty()) { + mSpeed = getAverageSpeedFromScanResults(mScoreCache, mCurrentHomeScanResults); + } else { + mSpeed = getAverageSpeedFromScanResults(mScoreCache, + mCurrentRoamingScanResults); + } + } + } notifyOnUpdated(); } diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java index be0c7fd94..c6b5454b0 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/SavedNetworkTracker.java @@ -169,6 +169,17 @@ public class SavedNetworkTracker extends BaseWifiTracker { updateSubscriptionWifiEntries(); } + @WorkerThread + @Override + protected void handleNetworkScoreCacheUpdated() { + for (StandardWifiEntry entry : mStandardWifiEntryCache.values()) { + entry.onScoreCacheUpdated(); + } + for (PasspointWifiEntry entry : mPasspointWifiEntryCache.values()) { + entry.onScoreCacheUpdated(); + } + } + private void updateSavedWifiEntries() { synchronized (mLock) { mSavedWifiEntries.clear(); @@ -300,7 +311,7 @@ public class SavedNetworkTracker extends BaseWifiTracker { if (changeReason != WifiManager.CHANGE_REASON_REMOVED) { mStandardWifiEntryCache.put(key, new StandardWifiEntry(mContext, mMainHandler, key, config, mWifiManager, - true /* forSavedNetworksPage */)); + mWifiNetworkScoreCache, true /* forSavedNetworksPage */)); } } } @@ -328,7 +339,7 @@ public class SavedNetworkTracker extends BaseWifiTracker { for (String key : wifiConfigsByKey.keySet()) { mStandardWifiEntryCache.put(key, new StandardWifiEntry(mContext, mMainHandler, key, wifiConfigsByKey.get(key), - mWifiManager, true /* forSavedNetworksPage */)); + mWifiManager, mWifiNetworkScoreCache, true /* forSavedNetworksPage */)); } } @@ -359,7 +370,7 @@ public class SavedNetworkTracker extends BaseWifiTracker { for (String key : passpointConfigsByKey.keySet()) { mPasspointWifiEntryCache.put(key, new PasspointWifiEntry(mContext, mMainHandler, passpointConfigsByKey.get(key), - mWifiManager, true /* forSavedNetworksPage */)); + mWifiManager, mWifiNetworkScoreCache, true /* forSavedNetworksPage */)); } } diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java index f97ae643f..aee8ca37c 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardNetworkDetailsTracker.java @@ -68,7 +68,7 @@ class StandardNetworkDetailsTracker extends NetworkDetailsTracker { super(lifecycle, context, wifiManager, connectivityManager, networkScoreManager, mainHandler, workerHandler, clock, maxScanAgeMillis, scanIntervalMillis, TAG); mChosenEntry = new StandardWifiEntry(mContext, mMainHandler, key, mWifiManager, - false /* forSavedNetworksPage */); + mWifiNetworkScoreCache, false /* forSavedNetworksPage */); cacheNewScanResults(); conditionallyUpdateScanResults(true /* lastScanSucceeded */); conditionallyUpdateConfig(); @@ -153,6 +153,12 @@ class StandardNetworkDetailsTracker extends NetworkDetailsTracker { } } + @WorkerThread + @Override + protected void handleNetworkScoreCacheUpdated() { + mChosenEntry.onScoreCacheUpdated(); + } + /** * Updates the tracked entry's scan results up to the max scan age (or more, if the last scan * was unsuccessful). If Wifi is disabled, the tracked entry's level will be cleared. diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java index 4a1be50f4..06b27656a 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java @@ -28,6 +28,7 @@ import static com.android.wifitrackerlib.Utils.getAppLabel; import static com.android.wifitrackerlib.Utils.getAppLabelForSavedNetwork; import static com.android.wifitrackerlib.Utils.getAppLabelForWifiConfiguration; import static com.android.wifitrackerlib.Utils.getAutoConnectDescription; +import static com.android.wifitrackerlib.Utils.getAverageSpeedFromScanResults; import static com.android.wifitrackerlib.Utils.getBestScanResultByLevel; import static com.android.wifitrackerlib.Utils.getCarrierNameForSubId; import static com.android.wifitrackerlib.Utils.getCurrentNetworkCapabilitiesInformation; @@ -37,6 +38,7 @@ import static com.android.wifitrackerlib.Utils.getMeteredDescription; import static com.android.wifitrackerlib.Utils.getNetworkDetailedState; import static com.android.wifitrackerlib.Utils.getSecurityTypeFromWifiConfiguration; import static com.android.wifitrackerlib.Utils.getSpeedDescription; +import static com.android.wifitrackerlib.Utils.getSpeedFromWifiInfo; import static com.android.wifitrackerlib.Utils.getSubIdForConfig; import static com.android.wifitrackerlib.Utils.getVerboseLoggingDescription; @@ -51,6 +53,7 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration.NetworkSelectionStatus; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; +import android.net.wifi.WifiNetworkScoreCache; import android.os.Handler; import android.os.SystemClock; import android.text.TextUtils; @@ -129,8 +132,10 @@ public class StandardWifiEntry extends WifiEntry { @NonNull String key, @NonNull List scanResults, @NonNull WifiManager wifiManager, + @NonNull WifiNetworkScoreCache scoreCache, boolean forSavedNetworksPage) throws IllegalArgumentException { - this(context, callbackHandler, key, wifiManager, forSavedNetworksPage); + this(context, callbackHandler, key, wifiManager, scoreCache, + forSavedNetworksPage); checkNotNull(scanResults, "Cannot construct with null ScanResult list!"); if (scanResults.isEmpty()) { @@ -143,8 +148,10 @@ public class StandardWifiEntry extends WifiEntry { StandardWifiEntry(@NonNull Context context, @NonNull Handler callbackHandler, @NonNull String key, @NonNull WifiConfiguration config, @NonNull WifiManager wifiManager, + @NonNull WifiNetworkScoreCache scoreCache, boolean forSavedNetworksPage) throws IllegalArgumentException { - this(context, callbackHandler, key, wifiManager, forSavedNetworksPage); + this(context, callbackHandler, key, wifiManager, scoreCache, + forSavedNetworksPage); checkNotNull(config, "Cannot construct with null config!"); checkNotNull(config.SSID, "Supplied config must have an SSID!"); @@ -153,9 +160,11 @@ public class StandardWifiEntry extends WifiEntry { } StandardWifiEntry(@NonNull Context context, @NonNull Handler callbackHandler, - @NonNull String key, @NonNull WifiManager wifiManager, boolean forSavedNetworksPage) { + @NonNull String key, @NonNull WifiManager wifiManager, + @NonNull WifiNetworkScoreCache scoreCache, + boolean forSavedNetworksPage) { // TODO: second argument (isSaved = false) is bogus in this context - super(callbackHandler, wifiManager, forSavedNetworksPage); + super(callbackHandler, wifiManager, scoreCache, forSavedNetworksPage); if (!key.startsWith(KEY_PREFIX)) { throw new IllegalArgumentException("Key does not start with correct prefix!"); @@ -186,11 +195,6 @@ public class StandardWifiEntry extends WifiEntry { public String getSummary(boolean concise) { StringJoiner sj = new StringJoiner(mContext.getString(R.string.summary_separator)); - final String speedDescription = getSpeedDescription(mContext, this); - if (!TextUtils.isEmpty(speedDescription)) { - sj.add(speedDescription); - } - if (!concise && mForSavedNetworksPage && isSaved()) { final CharSequence appLabel = getAppLabelForSavedNetwork(mContext, this); if (!TextUtils.isEmpty(appLabel)) { @@ -225,6 +229,11 @@ public class StandardWifiEntry extends WifiEntry { } } + final String speedDescription = getSpeedDescription(mContext, this); + if (!TextUtils.isEmpty(speedDescription)) { + sj.add(speedDescription); + } + final String autoConnectDescription = getAutoConnectDescription(mContext, this); if (!TextUtils.isEmpty(autoConnectDescription)) { sj.add(autoConnectDescription); @@ -284,11 +293,6 @@ public class StandardWifiEntry extends WifiEntry { ? getImsiProtectionDescription(mContext, getWifiConfiguration()) : ""; } - @Override - public int getLevel() { - return mLevel; - } - @Override public String getSsid() { return mSsid; @@ -702,6 +706,10 @@ public class StandardWifiEntry extends WifiEntry { mLevel = bestScanResult != null ? mWifiManager.calculateSignalLevel(bestScanResult.level) : WIFI_LEVEL_UNREACHABLE; + synchronized (mLock) { + // Average speed is used to prevent speed label flickering from multiple APs. + mSpeed = getAverageSpeedFromScanResults(mScoreCache, mCurrentScanResults); + } } notifyOnUpdated(); } @@ -718,6 +726,19 @@ public class StandardWifiEntry extends WifiEntry { } } + @WorkerThread + void onScoreCacheUpdated() { + if (mWifiInfo != null) { + mSpeed = getSpeedFromWifiInfo(mScoreCache, mWifiInfo); + } else { + synchronized (mLock) { + // Average speed is used to prevent speed label flickering from multiple APs. + mSpeed = getAverageSpeedFromScanResults(mScoreCache, mCurrentScanResults); + } + } + notifyOnUpdated(); + } + private void updateEapType(ScanResult result) { if (result.capabilities.contains("RSN-EAP")) { // WPA2-Enterprise and WPA3-Enterprise (non 192-bit) advertise RSN-EAP-CCMP diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java index 00a8dcf30..78617ba5a 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java @@ -27,6 +27,12 @@ import static com.android.wifitrackerlib.WifiEntry.SECURITY_OWE; import static com.android.wifitrackerlib.WifiEntry.SECURITY_PSK; import static com.android.wifitrackerlib.WifiEntry.SECURITY_SAE; import static com.android.wifitrackerlib.WifiEntry.SECURITY_WEP; +import static com.android.wifitrackerlib.WifiEntry.SPEED_FAST; +import static com.android.wifitrackerlib.WifiEntry.SPEED_MODERATE; +import static com.android.wifitrackerlib.WifiEntry.SPEED_NONE; +import static com.android.wifitrackerlib.WifiEntry.SPEED_SLOW; +import static com.android.wifitrackerlib.WifiEntry.SPEED_VERY_FAST; +import static com.android.wifitrackerlib.WifiEntry.Speed; import static java.util.Comparator.comparingInt; import static java.util.stream.Collectors.groupingBy; @@ -39,9 +45,13 @@ import android.content.pm.PackageManager; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; +import android.net.NetworkKey; +import android.net.ScoredNetwork; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration.NetworkSelectionStatus; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiNetworkScoreCache; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.UserHandle; @@ -301,6 +311,53 @@ class Utils { return scanResultsByKey; } + @Speed + static int getAverageSpeedFromScanResults(@NonNull WifiNetworkScoreCache scoreCache, + @NonNull List scanResults) { + int count = 0; + int totalSpeed = 0; + for (ScanResult scanResult : scanResults) { + ScoredNetwork scoredNetwork = scoreCache.getScoredNetwork(scanResult); + if (scoredNetwork == null) { + continue; + } + @Speed int speed = scoredNetwork.calculateBadge(scanResult.level); + if (speed != SPEED_NONE) { + count++; + totalSpeed += speed; + } + } + if (count == 0) { + return SPEED_NONE; + } else { + return roundToClosestSpeedEnum(totalSpeed / count); + } + } + + @Speed + static int getSpeedFromWifiInfo(@NonNull WifiNetworkScoreCache scoreCache, + @NonNull WifiInfo wifiInfo) { + ScoredNetwork scoredNetwork = scoreCache.getScoredNetwork( + NetworkKey.createFromWifiInfo(wifiInfo)); + if (scoredNetwork == null) { + return SPEED_NONE; + } + return roundToClosestSpeedEnum(scoredNetwork.calculateBadge(wifiInfo.getRssi())); + } + + @Speed + private static int roundToClosestSpeedEnum(int speed) { + if (speed < (SPEED_SLOW + SPEED_MODERATE) / 2) { + return SPEED_SLOW; + } else if (speed < (SPEED_MODERATE + SPEED_FAST) / 2) { + return SPEED_MODERATE; + } else if (speed < (SPEED_FAST + SPEED_VERY_FAST) / 2) { + return SPEED_FAST; + } else { + return SPEED_VERY_FAST; + } + } + static CharSequence getAppLabel(Context context, String packageName) { try { ApplicationInfo appInfo = context.getPackageManager().getApplicationInfoAsUser( @@ -421,11 +478,24 @@ class Utils { } static String getSpeedDescription(@NonNull Context context, @NonNull WifiEntry wifiEntry) { - // TODO(b/70983952): Fill this method in. if (context == null || wifiEntry == null) { return ""; } - return ""; + + @Speed int speed = wifiEntry.getSpeed(); + switch (speed) { + case SPEED_VERY_FAST: + return context.getString(R.string.speed_label_very_fast); + case SPEED_FAST: + return context.getString(R.string.speed_label_fast); + case SPEED_MODERATE: + return context.getString(R.string.speed_label_okay); + case SPEED_SLOW: + return context.getString(R.string.speed_label_slow); + case SPEED_NONE: + default: + return ""; + } } static String getVerboseLoggingDescription(@NonNull WifiEntry wifiEntry) { diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java index fb43d4bd2..e800e4832 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java @@ -20,6 +20,8 @@ import static android.net.wifi.WifiInfo.INVALID_RSSI; import static androidx.core.util.Preconditions.checkNotNull; +import static com.android.wifitrackerlib.Utils.getSpeedFromWifiInfo; + import android.net.LinkAddress; import android.net.LinkProperties; import android.net.NetworkCapabilities; @@ -29,6 +31,7 @@ import android.net.RouteInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; +import android.net.wifi.WifiNetworkScoreCache; import android.os.Handler; import androidx.annotation.AnyThread; @@ -102,6 +105,23 @@ public abstract class WifiEntry implements Comparable { public static final int WIFI_LEVEL_MAX = 4; public static final int WIFI_LEVEL_UNREACHABLE = -1; + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = { + SPEED_NONE, + SPEED_SLOW, + SPEED_MODERATE, + SPEED_FAST, + SPEED_VERY_FAST + }) + + public @interface Speed {} + + public static final int SPEED_NONE = 0; + public static final int SPEED_SLOW = 5; + public static final int SPEED_MODERATE = 10; + public static final int SPEED_FAST = 20; + public static final int SPEED_VERY_FAST = 30; + @Retention(RetentionPolicy.SOURCE) @IntDef(value = { METERED_CHOICE_AUTO, @@ -189,10 +209,12 @@ public abstract class WifiEntry implements Comparable { protected Handler mCallbackHandler; protected int mLevel = WIFI_LEVEL_UNREACHABLE; + protected int mSpeed = SPEED_NONE; protected WifiInfo mWifiInfo; protected NetworkInfo mNetworkInfo; protected NetworkCapabilities mNetworkCapabilities; protected ConnectedInfo mConnectedInfo; + protected WifiNetworkScoreCache mScoreCache; protected ConnectCallback mConnectCallback; protected DisconnectCallback mDisconnectCallback; @@ -202,12 +224,14 @@ public abstract class WifiEntry implements Comparable { protected boolean mCalledDisconnect = false; WifiEntry(@NonNull Handler callbackHandler, @NonNull WifiManager wifiManager, + @NonNull WifiNetworkScoreCache scoreCache, boolean forSavedNetworksPage) throws IllegalArgumentException { checkNotNull(callbackHandler, "Cannot construct with null handler!"); checkNotNull(wifiManager, "Cannot construct with null WifiManager!"); mCallbackHandler = callbackHandler; mForSavedNetworksPage = forSavedNetworksPage; mWifiManager = wifiManager; + mScoreCache = scoreCache; } // Info available for all WifiEntries // @@ -261,7 +285,15 @@ public abstract class WifiEntry implements Comparable { * Returns the signal strength level within [WIFI_LEVEL_MIN, WIFI_LEVEL_MAX]. * A value of WIFI_LEVEL_UNREACHABLE indicates an out of range network. */ - public abstract int getLevel(); + public int getLevel() { + return mLevel; + }; + + /** Returns the speed value of the network defined by the SPEED constants */ + @Speed + public int getSpeed() { + return mSpeed; + }; /** * Returns the SSID of the entry, if applicable. Null otherwise. @@ -585,6 +617,7 @@ public abstract class WifiEntry implements Comparable { final int wifiInfoRssi = wifiInfo.getRssi(); if (wifiInfoRssi != INVALID_RSSI) { mLevel = mWifiManager.calculateSignalLevel(wifiInfoRssi); + mSpeed = getSpeedFromWifiInfo(mScoreCache, wifiInfo); } if (getConnectedState() == CONNECTED_STATE_CONNECTED) { if (mCalledConnect) { diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java index 6e74e2eba..10c3f65c5 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiPickerTracker.java @@ -275,6 +275,20 @@ public class WifiPickerTracker extends BaseWifiTracker { } } + @WorkerThread + @Override + protected void handleNetworkScoreCacheUpdated() { + for (StandardWifiEntry entry : mStandardWifiEntryCache.values()) { + entry.onScoreCacheUpdated(); + } + for (StandardWifiEntry entry : mSuggestedWifiEntryCache.values()) { + entry.onScoreCacheUpdated(); + } + for (PasspointWifiEntry entry : mPasspointWifiEntryCache.values()) { + entry.onScoreCacheUpdated(); + } + } + /** * Update the list returned by getWifiEntries() with the current states of the entry caches. */ @@ -375,7 +389,8 @@ public class WifiPickerTracker extends BaseWifiTracker { // Create new StandardWifiEntry objects for each leftover group of scan results. for (Map.Entry> e: scanResultsByKey.entrySet()) { final StandardWifiEntry newEntry = new StandardWifiEntry(mContext, mMainHandler, - e.getKey(), e.getValue(), mWifiManager, false /* forSavedNetworksPage */); + e.getKey(), e.getValue(), mWifiManager, mWifiNetworkScoreCache, + false /* forSavedNetworksPage */); // Populate with a saved config, if available newEntry.updateConfig(mWifiConfigCache.get(newEntry.getKey())); mStandardWifiEntryCache.put(newEntry.getKey(), newEntry); @@ -415,7 +430,7 @@ public class WifiPickerTracker extends BaseWifiTracker { if (!mSuggestedWifiEntryCache.containsKey(key)) { mSuggestedWifiEntryCache.put(key, new StandardWifiEntry(mContext, mMainHandler, key, userSharedConfigsByKey.get(key), mWifiManager, - false /* forSavedNetworksPage */)); + mWifiNetworkScoreCache, false /* forSavedNetworksPage */)); } final StandardWifiEntry entry = mSuggestedWifiEntryCache.get(key); entry.setUserShareable(true); @@ -457,11 +472,11 @@ public class WifiPickerTracker extends BaseWifiTracker { if (wifiConfig.fromWifiNetworkSuggestion) { mPasspointWifiEntryCache.put(key, new PasspointWifiEntry(mContext, mMainHandler, wifiConfig, mWifiManager, - false /* forSavedNetworksPage */)); + mWifiNetworkScoreCache, false /* forSavedNetworksPage */)); } else if (mPasspointConfigCache.containsKey(key)) { mPasspointWifiEntryCache.put(key, new PasspointWifiEntry(mContext, mMainHandler, mPasspointConfigCache.get(key), mWifiManager, - false /* forSavedNetworksPage */)); + mWifiNetworkScoreCache, false /* forSavedNetworksPage */)); } else { // Failed to find PasspointConfig for a provisioned Passpoint network continue; @@ -494,7 +509,7 @@ public class WifiPickerTracker extends BaseWifiTracker { // Create a new entry for each OsuProvider not already matched to an OsuWifiEntry for (OsuProvider provider : osuProviderToScans.keySet()) { OsuWifiEntry newEntry = new OsuWifiEntry(mContext, mMainHandler, provider, mWifiManager, - false /* forSavedNetworksPage */); + mWifiNetworkScoreCache, false /* forSavedNetworksPage */); newEntry.updateScanResultInfo(osuProviderToScans.get(provider)); mOsuWifiEntryCache.put(osuProviderToOsuWifiEntryKey(provider), newEntry); } @@ -691,7 +706,7 @@ public class WifiPickerTracker extends BaseWifiTracker { final StandardWifiEntry connectedEntry = new StandardWifiEntry(mContext, mMainHandler, wifiConfigToStandardWifiEntryKey(config), config, mWifiManager, - false /* forSavedNetworksPage */); + mWifiNetworkScoreCache, false /* forSavedNetworksPage */); connectedEntry.updateConnectionInfo(wifiInfo, networkInfo); mStandardWifiEntryCache.put(connectedEntry.getKey(), connectedEntry); }); @@ -720,7 +735,7 @@ public class WifiPickerTracker extends BaseWifiTracker { final StandardWifiEntry connectedEntry = new StandardWifiEntry(mContext, mMainHandler, wifiConfigToStandardWifiEntryKey(config), config, mWifiManager, - false /* forSavedNetworksPage */); + mWifiNetworkScoreCache, false /* forSavedNetworksPage */); connectedEntry.updateConnectionInfo(wifiInfo, networkInfo); mSuggestedWifiEntryCache.put(connectedEntry.getKey(), connectedEntry); }); @@ -752,11 +767,13 @@ public class WifiPickerTracker extends BaseWifiTracker { PasspointWifiEntry connectedEntry; if (passpointConfig != null) { connectedEntry = new PasspointWifiEntry(mContext, mMainHandler, - passpointConfig, mWifiManager, false /* forSavedNetworksPage */); + passpointConfig, mWifiManager, mWifiNetworkScoreCache, + false /* forSavedNetworksPage */); } else { // Suggested PasspointWifiEntry without a corresponding Passpoint config connectedEntry = new PasspointWifiEntry(mContext, mMainHandler, - wifiConfig, mWifiManager, false /* forSavedNetworksPage */); + wifiConfig, mWifiManager, mWifiNetworkScoreCache, + false /* forSavedNetworksPage */); } connectedEntry.updateConnectionInfo(wifiInfo, networkInfo); mPasspointWifiEntryCache.put(connectedEntry.getKey(), connectedEntry); diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/PasspointWifiEntryTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/PasspointWifiEntryTest.java index 85bad0d39..80a31e53f 100644 --- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/PasspointWifiEntryTest.java +++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/PasspointWifiEntryTest.java @@ -16,8 +16,13 @@ package com.android.wifitrackerlib; +import static com.android.wifitrackerlib.TestUtils.buildScanResult; +import static com.android.wifitrackerlib.WifiEntry.SPEED_FAST; +import static com.android.wifitrackerlib.WifiEntry.SPEED_SLOW; + import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -26,8 +31,13 @@ import android.content.Context; import android.content.res.Resources; import android.net.ConnectivityManager; import android.net.NetworkInfo; +import android.net.NetworkKey; +import android.net.ScoredNetwork; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; +import android.net.wifi.WifiNetworkScoreCache; import android.net.wifi.hotspot2.PasspointConfiguration; import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.HomeSp; @@ -39,10 +49,20 @@ import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.Collections; + public class PasspointWifiEntryTest { + public static final int GOOD_RSSI = -50; + public static final int OKAY_RSSI = -60; + public static final int BAD_RSSI = -70; + @Mock private Context mMockContext; @Mock private WifiManager mMockWifiManager; @Mock private Resources mMockResources; + @Mock private WifiInfo mMockWifiInfo; + @Mock private NetworkInfo mMockNetworkInfo; + @Mock private WifiNetworkScoreCache mMockScoreCache; + @Mock private ScoredNetwork mMockScoredNetwork; private TestLooper mTestLooper; private Handler mTestHandler; @@ -56,8 +76,14 @@ public class PasspointWifiEntryTest { mTestLooper = new TestLooper(); mTestHandler = new Handler(mTestLooper.getLooper()); + when(mMockWifiInfo.getNetworkId()).thenReturn(WifiConfiguration.INVALID_NETWORK_ID); + when(mMockWifiInfo.getRssi()).thenReturn(WifiInfo.INVALID_RSSI); + when(mMockNetworkInfo.getDetailedState()).thenReturn( + NetworkInfo.DetailedState.DISCONNECTED); when(mMockContext.getResources()).thenReturn(mMockResources); when(mMockResources.getString(R.string.summary_separator)).thenReturn("/"); + when(mMockScoreCache.getScoredNetwork((ScanResult) any())).thenReturn(mMockScoredNetwork); + when(mMockScoreCache.getScoredNetwork((NetworkKey) any())).thenReturn(mMockScoredNetwork); } @Test @@ -68,7 +94,8 @@ public class PasspointWifiEntryTest { when(mMockResources.getString(R.string.wifi_passpoint_expired)).thenReturn(expired); PasspointWifiEntry passpointWifiEntry = new PasspointWifiEntry(mMockContext, mTestHandler, - passpointConfiguration, mMockWifiManager, false /* forSavedNetworksPage */); + passpointConfiguration, mMockWifiManager, mMockScoreCache, + false /* forSavedNetworksPage */); assertThat(passpointWifiEntry.getSummary()).isNotEqualTo(expired); } @@ -79,7 +106,8 @@ public class PasspointWifiEntryTest { String expired = "Expired"; when(mMockResources.getString(R.string.wifi_passpoint_expired)).thenReturn(expired); PasspointWifiEntry passpointWifiEntry = new PasspointWifiEntry(mMockContext, mTestHandler, - passpointConfiguration, mMockWifiManager, false /* forSavedNetworksPage */); + passpointConfiguration, mMockWifiManager, mMockScoreCache, + false /* forSavedNetworksPage */); PasspointWifiEntry spyEntry = spy(passpointWifiEntry); when(spyEntry.isExpired()).thenReturn(true); @@ -98,7 +126,8 @@ public class PasspointWifiEntryTest { @Test public void testGetMeteredChoice_afterSetMeteredChoice_getCorrectValue() { PasspointWifiEntry entry = new PasspointWifiEntry(mMockContext, mTestHandler, - getPasspointConfiguration(), mMockWifiManager, false /* forSavedNetworksPage */); + getPasspointConfiguration(), mMockWifiManager, mMockScoreCache, + false /* forSavedNetworksPage */); entry.setMeteredChoice(WifiEntry.METERED_CHOICE_UNMETERED); @@ -127,9 +156,69 @@ public class PasspointWifiEntryTest { networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", ""); PasspointWifiEntry entry = new PasspointWifiEntry(mMockContext, mTestHandler, - getPasspointConfiguration(), mMockWifiManager, false /* forSavedNetworksPage */); + getPasspointConfiguration(), mMockWifiManager, mMockScoreCache, + false /* forSavedNetworksPage */); entry.updateConnectionInfo(wifiInfo, networkInfo); assertThat(entry.getSummary()).isEqualTo("Connected"); } + + @Test + public void testGetSpeed_cacheUpdated_speedValueChanges() { + when(mMockScoredNetwork.calculateBadge(GOOD_RSSI)).thenReturn(SPEED_FAST); + PasspointWifiEntry entry = new PasspointWifiEntry(mMockContext, mTestHandler, + getPasspointConfiguration(), mMockWifiManager, mMockScoreCache, + false /* forSavedNetworksPage */); + WifiConfiguration wifiConfig = new WifiConfiguration(); + wifiConfig.FQDN = FQDN; + entry.updateScanResultInfo(wifiConfig, + Collections.singletonList(buildScanResult("ssid", "bssid0", 0, GOOD_RSSI)), + null); + + when(mMockScoredNetwork.calculateBadge(GOOD_RSSI)).thenReturn(SPEED_SLOW); + entry.onScoreCacheUpdated(); + + assertThat(entry.getSpeed()).isEqualTo(SPEED_SLOW); + } + + @Test + public void testGetSpeed_connected_useWifiInfoRssiForSpeed() { + when(mMockScoredNetwork.calculateBadge(BAD_RSSI)).thenReturn(SPEED_SLOW); + when(mMockScoredNetwork.calculateBadge(GOOD_RSSI)).thenReturn(SPEED_FAST); + when(mMockWifiInfo.isPasspointAp()).thenReturn(true); + when(mMockWifiInfo.getPasspointFqdn()).thenReturn(FQDN); + when(mMockWifiInfo.getRssi()).thenReturn(BAD_RSSI); + PasspointWifiEntry entry = new PasspointWifiEntry(mMockContext, mTestHandler, + getPasspointConfiguration(), mMockWifiManager, mMockScoreCache, + false /* forSavedNetworksPage */); + WifiConfiguration wifiConfig = new WifiConfiguration(); + wifiConfig.FQDN = FQDN; + entry.updateScanResultInfo(wifiConfig, + Collections.singletonList(buildScanResult("ssid", "bssid0", 0, GOOD_RSSI)), + null); + + entry.updateConnectionInfo(mMockWifiInfo, mMockNetworkInfo); + + assertThat(entry.getSpeed()).isEqualTo(SPEED_SLOW); + } + + @Test + public void testGetSpeed_newScanResults_speedValueChanges() { + when(mMockScoredNetwork.calculateBadge(BAD_RSSI)).thenReturn(SPEED_SLOW); + when(mMockScoredNetwork.calculateBadge(GOOD_RSSI)).thenReturn(SPEED_FAST); + PasspointWifiEntry entry = new PasspointWifiEntry(mMockContext, mTestHandler, + getPasspointConfiguration(), mMockWifiManager, mMockScoreCache, + false /* forSavedNetworksPage */); + WifiConfiguration wifiConfig = new WifiConfiguration(); + wifiConfig.FQDN = FQDN; + entry.updateScanResultInfo(wifiConfig, + Collections.singletonList(buildScanResult("ssid", "bssid0", 0, GOOD_RSSI)), + null); + + entry.updateScanResultInfo(wifiConfig, + Collections.singletonList(buildScanResult("ssid", "bssid0", 0, BAD_RSSI)), + null); + + assertThat(entry.getSpeed()).isEqualTo(SPEED_SLOW); + } } diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java index 63b096ecc..b9a0ca12b 100644 --- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java +++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/StandardWifiEntryTest.java @@ -32,6 +32,8 @@ import static com.android.wifitrackerlib.WifiEntry.SECURITY_NONE; import static com.android.wifitrackerlib.WifiEntry.SECURITY_OWE; import static com.android.wifitrackerlib.WifiEntry.SECURITY_PSK; import static com.android.wifitrackerlib.WifiEntry.SECURITY_WEP; +import static com.android.wifitrackerlib.WifiEntry.SPEED_FAST; +import static com.android.wifitrackerlib.WifiEntry.SPEED_SLOW; import static com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_UNREACHABLE; import static com.google.common.truth.Truth.assertThat; @@ -53,12 +55,15 @@ import android.net.LinkProperties; import android.net.MacAddress; import android.net.NetworkCapabilities; import android.net.NetworkInfo; +import android.net.NetworkKey; import android.net.NetworkScoreManager; +import android.net.ScoredNetwork; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration.NetworkSelectionStatus; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; +import android.net.wifi.WifiNetworkScoreCache; import android.os.Handler; import android.os.test.TestLooper; @@ -69,6 +74,7 @@ import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; public class StandardWifiEntryTest { public static final int GOOD_RSSI = -50; @@ -87,6 +93,8 @@ public class StandardWifiEntryTest { @Mock private NetworkInfo mMockNetworkInfo; @Mock private Context mMockContext; @Mock private NetworkScoreManager mMockNetworkScoreManager; + @Mock private WifiNetworkScoreCache mMockScoreCache; + @Mock private ScoredNetwork mMockScoredNetwork; private TestLooper mTestLooper; private Handler mTestHandler; @@ -110,6 +118,8 @@ public class StandardWifiEntryTest { .thenReturn(BAD_LEVEL); when(mMockContext.getSystemService(Context.NETWORK_SCORE_SERVICE)) .thenReturn(mMockNetworkScoreManager); + when(mMockScoreCache.getScoredNetwork((ScanResult) any())).thenReturn(mMockScoredNetwork); + when(mMockScoreCache.getScoredNetwork((NetworkKey) any())).thenReturn(mMockScoredNetwork); } /** @@ -120,7 +130,8 @@ public class StandardWifiEntryTest { try { new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_NONE), - new ArrayList<>(), mMockWifiManager, false /* forSavedNetworksPage */); + new ArrayList<>(), mMockWifiManager, mMockScoreCache, + false /* forSavedNetworksPage */); fail("Empty scan list should have thrown exception"); } catch (IllegalArgumentException e) { // Test succeeded @@ -138,7 +149,7 @@ public class StandardWifiEntryTest { Arrays.asList( buildScanResult("ssid0", "bssid0", 0, GOOD_RSSI), buildScanResult("ssid1", "bssid1", 0, GOOD_RSSI)), - mMockWifiManager, false /* forSavedNetworksPage */); + mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); fail("Scan list with different SSIDs should have thrown exception"); } catch (IllegalArgumentException e) { // Test succeeded @@ -156,7 +167,7 @@ public class StandardWifiEntryTest { buildScanResult("ssid", "bssid0", 0, GOOD_RSSI), buildScanResult("ssid", "bssid1", 0, OKAY_RSSI), buildScanResult("ssid", "bssid2", 0, BAD_RSSI)), - mMockWifiManager, false /* forSavedNetworksPage */); + mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); assertThat(entry.getLevel()).isEqualTo(GOOD_LEVEL); } @@ -172,10 +183,12 @@ public class StandardWifiEntryTest { final StandardWifiEntry unsecureEntry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_NONE), - Arrays.asList(unsecureScan), mMockWifiManager, false /* forSavedNetworksPage */); + Arrays.asList(unsecureScan), mMockWifiManager, mMockScoreCache, + false /* forSavedNetworksPage */); final StandardWifiEntry secureEntry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_EAP), - Arrays.asList(secureScan), mMockWifiManager, false /* forSavedNetworksPage */); + Arrays.asList(secureScan), mMockWifiManager, mMockScoreCache, + false /* forSavedNetworksPage */); assertThat(unsecureEntry.getSecurity()).isEqualTo(WifiEntry.SECURITY_NONE); assertThat(secureEntry.getSecurity()).isEqualTo(WifiEntry.SECURITY_EAP); @@ -189,7 +202,7 @@ public class StandardWifiEntryTest { final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid0", SECURITY_EAP), Arrays.asList(buildScanResult("ssid0", "bssid0", 0, GOOD_RSSI)), - mMockWifiManager, false /* forSavedNetworksPage */); + mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); try { entry.updateScanResultInfo(Arrays.asList( @@ -208,7 +221,7 @@ public class StandardWifiEntryTest { final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_NONE), Arrays.asList(buildScanResult("ssid", "bssid", 0)), - mMockWifiManager, false /* forSavedNetworksPage */); + mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); entry.setListener(mMockListener); entry.updateScanResultInfo(Arrays.asList(buildScanResult("ssid", "bssid", 1))); @@ -225,7 +238,7 @@ public class StandardWifiEntryTest { final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_NONE), Arrays.asList(buildScanResult("ssid", "bssid", 0, BAD_RSSI)), - mMockWifiManager, false /* forSavedNetworksPage */); + mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); assertThat(entry.getLevel()).isEqualTo(BAD_LEVEL); @@ -241,7 +254,7 @@ public class StandardWifiEntryTest { config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_EAP), - config, mMockWifiManager, false /* forSavedNetworksPage */); + config, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); assertThat(entry.getTitle()).isEqualTo("ssid"); } @@ -253,7 +266,7 @@ public class StandardWifiEntryTest { config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_EAP), - config, mMockWifiManager, false /* forSavedNetworksPage */); + config, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); assertThat(entry.getSecurity()).isEqualTo(WifiEntry.SECURITY_EAP); } @@ -265,7 +278,7 @@ public class StandardWifiEntryTest { config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_EAP), - config, mMockWifiManager, false /* forSavedNetworksPage */); + config, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); final WifiConfiguration config2 = new WifiConfiguration(config); config2.SSID = "\"ssid2\""; @@ -284,7 +297,7 @@ public class StandardWifiEntryTest { config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_WEP); final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_WEP), - config, mMockWifiManager, false /* forSavedNetworksPage */); + config, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); final WifiConfiguration config2 = new WifiConfiguration(config); config2.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP); @@ -302,7 +315,8 @@ public class StandardWifiEntryTest { scan.capabilities = "EAP"; final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_EAP), - Arrays.asList(scan), mMockWifiManager, false /* forSavedNetworksPage */); + Arrays.asList(scan), mMockWifiManager, mMockScoreCache, + false /* forSavedNetworksPage */); assertThat(entry.isSaved()).isFalse(); @@ -323,7 +337,7 @@ public class StandardWifiEntryTest { config.networkId = 1; final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_EAP), - config, mMockWifiManager, false /* forSavedNetworksPage */); + config, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); assertThat(entry.isSaved()).isTrue(); @@ -340,7 +354,7 @@ public class StandardWifiEntryTest { config.networkId = 1; final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_EAP), - config, mMockWifiManager, false /* forSavedNetworksPage */); + config, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); when(mMockWifiInfo.getNetworkId()).thenReturn(1); when(mMockWifiInfo.getRssi()).thenReturn(GOOD_RSSI); when(mMockNetworkInfo.getDetailedState()).thenReturn(NetworkInfo.DetailedState.CONNECTED); @@ -359,7 +373,7 @@ public class StandardWifiEntryTest { config.networkId = 1; final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_EAP), - config, mMockWifiManager, false /* forSavedNetworksPage */); + config, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); when(mMockWifiInfo.getNetworkId()).thenReturn(2); when(mMockWifiInfo.getRssi()).thenReturn(-50); when(mMockNetworkInfo.getDetailedState()).thenReturn(NetworkInfo.DetailedState.CONNECTED); @@ -375,7 +389,8 @@ public class StandardWifiEntryTest { final ScanResult scan = buildScanResult("ssid", "bssid", 0, GOOD_RSSI); final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_NONE), - Arrays.asList(scan), mMockWifiManager, false /* forSavedNetworksPage */); + Arrays.asList(scan), mMockWifiManager, mMockScoreCache, + false /* forSavedNetworksPage */); final WifiConfiguration config = new WifiConfiguration(); config.SSID = "\"ssid\""; config.networkId = 1; @@ -391,7 +406,7 @@ public class StandardWifiEntryTest { final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_NONE), Arrays.asList(buildScanResult("ssid", "bssid0", 0, GOOD_RSSI)), - mMockWifiManager, false /* forSavedNetworksPage */); + mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); entry.connect(null /* ConnectCallback */); @@ -404,7 +419,8 @@ public class StandardWifiEntryTest { secureScan.capabilities = "PSK"; final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_PSK), - Arrays.asList(secureScan), mMockWifiManager, false /* forSavedNetworksPage */); + Arrays.asList(secureScan), mMockWifiManager, mMockScoreCache, + false /* forSavedNetworksPage */); entry.setListener(mMockListener); entry.connect(mMockConnectCallback); @@ -428,7 +444,7 @@ public class StandardWifiEntryTest { final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_EAP), - spyConfig, mMockWifiManager, false /* forSavedNetworksPage */); + spyConfig, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); final String macAddress = entry.getMacAddress(); @@ -446,7 +462,7 @@ public class StandardWifiEntryTest { when(mMockWifiManager.getFactoryMacAddresses()).thenReturn(new String[]{factoryMac}); final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_EAP), - config, mMockWifiManager, false /* forSavedNetworksPage */); + config, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); final String macAddress = entry.getMacAddress(); @@ -492,7 +508,8 @@ public class StandardWifiEntryTest { final StandardWifiEntry pskWifiEntry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey(pskScanResult.SSID, SECURITY_PSK), - Arrays.asList(pskScanResult), mMockWifiManager, false /* forSavedNetworksPage */); + Arrays.asList(pskScanResult), mMockWifiManager, mMockScoreCache, + false /* forSavedNetworksPage */); assertThat(pskWifiEntry.canEasyConnect()).isFalse(); } @@ -538,7 +555,7 @@ public class StandardWifiEntryTest { config.networkId = 1; final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_EAP), - config, mMockWifiManager, false /* forSavedNetworksPage */); + config, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); when(mMockWifiInfo.getNetworkId()).thenReturn(1); when(mMockWifiInfo.getRssi()).thenReturn(GOOD_RSSI); when(mMockNetworkInfo.getDetailedState()).thenReturn(NetworkInfo.DetailedState.CONNECTED); @@ -555,7 +572,7 @@ public class StandardWifiEntryTest { config.setSecurityParams(wifiConfigurationSecureType); return new StandardWifiEntry(mMockContext, mTestHandler, wifiConfigToStandardWifiEntryKey(config), - config, mMockWifiManager, false /* forSavedNetworksPage */); + config, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); } @Test @@ -583,7 +600,7 @@ public class StandardWifiEntryTest { config.networkId = networkId; final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_NONE), config, - mMockWifiManager, false /* forSavedNetworksPage */); + mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); entry.updateConnectionInfo(wifiInfo, networkInfo); @@ -641,7 +658,7 @@ public class StandardWifiEntryTest { ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_NONE), Arrays.asList( buildScanResult("ssid", "bssid0", 0, GOOD_RSSI)), - mMockWifiManager, false /* forSavedNetworksPage */); + mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); NetworkCapabilities captivePortalCapabilities = new NetworkCapabilities(); captivePortalCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL); entry.updateNetworkCapabilities(captivePortalCapabilities); @@ -657,7 +674,7 @@ public class StandardWifiEntryTest { ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_NONE), Arrays.asList( buildScanResult("ssid", "bssid0", 0, GOOD_RSSI)), - mMockWifiManager, false /* forSavedNetworksPage */); + mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); NetworkCapabilities captivePortalCapabilities = new NetworkCapabilities(); captivePortalCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL); @@ -678,7 +695,7 @@ public class StandardWifiEntryTest { public void testShouldEditBeforeConnect_nullWifiConfig_returnFalse() { StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_EAP), - mMockWifiManager, false /* forSavedNetworksPage */); + mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); assertThat(entry.shouldEditBeforeConnect()).isFalse(); } @@ -691,7 +708,7 @@ public class StandardWifiEntryTest { wifiConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN); StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_NONE), - wifiConfig, mMockWifiManager, false /* forSavedNetworksPage */); + wifiConfig, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); assertThat(entry.shouldEditBeforeConnect()).isFalse(); @@ -699,7 +716,7 @@ public class StandardWifiEntryTest { wifiConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE); entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_OWE), - wifiConfig, mMockWifiManager, false /* forSavedNetworksPage */); + wifiConfig, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); assertThat(entry.shouldEditBeforeConnect()).isFalse(); } @@ -712,7 +729,7 @@ public class StandardWifiEntryTest { wifiConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK); StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_PSK), - wifiConfig, mMockWifiManager, false /* forSavedNetworksPage */); + wifiConfig, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); NetworkSelectionStatus networkSelectionStatus = spy(new NetworkSelectionStatus.Builder().build()); doReturn(networkSelectionStatus).when(wifiConfig).getNetworkSelectionStatus(); @@ -733,12 +750,12 @@ public class StandardWifiEntryTest { wifiConfig.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK); StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_PSK), - wifiConfig, mMockWifiManager, false /* forSavedNetworksPage */); + wifiConfig, mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); NetworkSelectionStatus.Builder statusBuilder = new NetworkSelectionStatus.Builder(); NetworkSelectionStatus networkSelectionStatus = spy(statusBuilder.setNetworkSelectionStatus( NETWORK_SELECTION_TEMPORARY_DISABLED) .setNetworkSelectionDisableReason( - DISABLED_AUTHENTICATION_FAILURE) + DISABLED_AUTHENTICATION_FAILURE) .build()); doReturn(1).when(networkSelectionStatus).getDisableReasonCounter( DISABLED_AUTHENTICATION_FAILURE); @@ -767,4 +784,53 @@ public class StandardWifiEntryTest { assertThat(entry.shouldEditBeforeConnect()).isTrue(); } + + @Test + public void testGetSpeed_cacheUpdated_speedValueChanges() { + when(mMockScoredNetwork.calculateBadge(GOOD_RSSI)).thenReturn(SPEED_FAST); + final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, + ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_NONE), + Collections.singletonList(buildScanResult("ssid", "bssid0", 0, GOOD_RSSI)), + mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); + + when(mMockScoredNetwork.calculateBadge(GOOD_RSSI)).thenReturn(SPEED_SLOW); + entry.onScoreCacheUpdated(); + + assertThat(entry.getSpeed()).isEqualTo(SPEED_SLOW); + } + + @Test + public void testGetSpeed_connected_useWifiInfoRssiForSpeed() { + when(mMockScoredNetwork.calculateBadge(BAD_RSSI)).thenReturn(SPEED_SLOW); + when(mMockScoredNetwork.calculateBadge(GOOD_RSSI)).thenReturn(SPEED_FAST); + when(mMockWifiInfo.getNetworkId()).thenReturn(1); + when(mMockWifiInfo.getRssi()).thenReturn(BAD_RSSI); + final WifiConfiguration config = new WifiConfiguration(); + config.SSID = "\"ssid\""; + config.networkId = 1; + final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, + ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_NONE), config, + mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); + entry.updateScanResultInfo(Collections.singletonList( + buildScanResult("ssid", "bssid0", 0, GOOD_RSSI))); + + entry.updateConnectionInfo(mMockWifiInfo, mMockNetworkInfo); + + assertThat(entry.getSpeed()).isEqualTo(SPEED_SLOW); + } + + @Test + public void testGetSpeed_newScanResults_speedValueChanges() { + when(mMockScoredNetwork.calculateBadge(BAD_RSSI)).thenReturn(SPEED_SLOW); + when(mMockScoredNetwork.calculateBadge(GOOD_RSSI)).thenReturn(SPEED_FAST); + final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, + ssidAndSecurityToStandardWifiEntryKey("ssid", SECURITY_NONE), + Collections.singletonList(buildScanResult("ssid", "bssid0", 0, GOOD_RSSI)), + mMockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); + + entry.updateScanResultInfo(Collections.singletonList( + buildScanResult("ssid", "bssid0", 0, BAD_RSSI))); + + assertThat(entry.getSpeed()).isEqualTo(SPEED_SLOW); + } } diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java index 0ee26dafa..aa0df1092 100644 --- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java +++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java @@ -54,6 +54,7 @@ import android.net.wifi.WifiConfiguration.NetworkSelectionStatus; import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; +import android.net.wifi.WifiNetworkScoreCache; import android.os.Handler; import android.os.PersistableBundle; import android.os.test.TestLooper; @@ -98,6 +99,7 @@ public class UtilsTest { @Mock private Context mMockContext; @Mock private Resources mMockResources; @Mock private NetworkScoreManager mMockNetworkScoreManager; + @Mock private WifiNetworkScoreCache mMockScoreCache; @Mock private SubscriptionManager mSubscriptionManager; @Mock private TelephonyManager mTelephonyManager; @Mock private CarrierConfigManager mCarrierConfigManager; @@ -209,7 +211,7 @@ public class UtilsTest { final CharSequence appLabel = getAppLabelForSavedNetwork(mMockContext, entry); - assertThat(appLabel).isEqualTo(APP_LABEL); + assertThat(appLabel.toString()).isEqualTo(APP_LABEL); } @Test @@ -380,7 +382,7 @@ public class UtilsTest { public void testGetImsiProtectionDescription_isSimCredentialFalse_returnEmptyString() { final WifiConfiguration wificonfig = new WifiConfiguration(); - assertEquals(getImsiProtectionDescription(mMockContext, wificonfig), ""); + assertEquals(getImsiProtectionDescription(mMockContext, wificonfig).toString(), ""); } @Test @@ -390,7 +392,7 @@ public class UtilsTest { when(mockWifiEnterpriseConfig.isAuthenticationSimBased()).thenReturn(true); mockWifiConfig.enterpriseConfig = mockWifiEnterpriseConfig; - assertEquals(getImsiProtectionDescription(mMockContext, mockWifiConfig), ""); + assertEquals(getImsiProtectionDescription(mMockContext, mockWifiConfig).toString(), ""); } @Test @@ -400,7 +402,7 @@ public class UtilsTest { final CharSequence output = linkifyAnnotation(mMockContext, testText, "id", "url"); final SpannableString outputSpannableString = new SpannableString(output); - assertEquals(output, testText); + assertEquals(output.toString(), testText); assertEquals(outputSpannableString.getSpans(0, outputSpannableString.length(), ClickableSpan.class).length, 0); } @@ -447,7 +449,7 @@ public class UtilsTest { final WifiManager mockWifiManager = mock(WifiManager.class); final StandardWifiEntry entry = new StandardWifiEntry(mMockContext, mTestHandler, wifiConfigToStandardWifiEntryKey(config), config, - mockWifiManager, false /* forSavedNetworksPage */); + mockWifiManager, mMockScoreCache, false /* forSavedNetworksPage */); final WifiInfo mockWifiInfo = mock(WifiInfo.class); final NetworkInfo mockNetworkInfo = mock(NetworkInfo.class); -- cgit v1.2.3