diff options
author | Michael Plass <mplass@google.com> | 2020-03-21 20:05:20 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-03-21 20:05:20 +0000 |
commit | 5086f8da98e4d1fe44033a3ef2a3be2d76b4e333 (patch) | |
tree | 778a53e742a298814f64d24ef5f59dea8d620e9a | |
parent | a2d7442bb5892c4a986a1e54d3f51abb10a9b66f (diff) | |
parent | c6f842d7676f0a20ca83d3482b5177b528b25503 (diff) |
Merge changes Ifc80ff6e,I24314151 into rvc-dev
* changes:
Prefer trusted networks to untrusted
[ThroughputScorer] Simplify last-selected bonus
10 files changed, 210 insertions, 51 deletions
diff --git a/service/java/com/android/server/wifi/BubbleFunScorer.java b/service/java/com/android/server/wifi/BubbleFunScorer.java index fd75751d2..e14fef0eb 100644 --- a/service/java/com/android/server/wifi/BubbleFunScorer.java +++ b/service/java/com/android/server/wifi/BubbleFunScorer.java @@ -65,7 +65,7 @@ final class BubbleFunScorer implements WifiCandidates.CandidateScorer { double score = shapeFunction(rssi) - shapeFunction(rssiEntryThreshold); // If we are below the entry threshold, make the score more negative - if (score < 0.0) score *= 10.0; + if (score < 0.0) score *= 2.0; // The gain is approximately the derivative of shapeFunction at the given rssi // This is used to estimate the error diff --git a/service/java/com/android/server/wifi/ScoringParams.java b/service/java/com/android/server/wifi/ScoringParams.java index 0a29b57c7..7588582b3 100644 --- a/service/java/com/android/server/wifi/ScoringParams.java +++ b/service/java/com/android/server/wifi/ScoringParams.java @@ -94,7 +94,9 @@ public class ScoringParams { public int unmeteredNetworkBonus = 1000; public int currentNetworkBonus = 20; public int secureNetworkBonus = 10; - public int lastSelectionBonus = 1999; + public int lastSelectionMinutes = 480; + public static final int MIN_MINUTES = 1; + public static final int MAX_MINUTES = Integer.MAX_VALUE / (60 * 1000); Values() { } @@ -125,6 +127,7 @@ public class ScoringParams { validateRange(horizon, MIN_HORIZON, MAX_HORIZON); validateRange(nud, MIN_NUD, MAX_NUD); validateRange(expid, MIN_EXPID, MAX_EXPID); + validateRange(lastSelectionMinutes, MIN_MINUTES, MAX_MINUTES); } private void validateRssiArray(int[] rssi) throws IllegalArgumentException { @@ -276,8 +279,8 @@ public class ScoringParams { R.integer.config_wifiFrameworkCurrentNetworkBonus); mVal.secureNetworkBonus = context.getResources().getInteger( R.integer.config_wifiFrameworkSecureNetworkBonus); - mVal.lastSelectionBonus = context.getResources().getInteger( - R.integer.config_wifiFrameworkLastSelectionBonus); + mVal.lastSelectionMinutes = context.getResources().getInteger( + R.integer.config_wifiFrameworkLastSelectionMinutes); mVal.pps[ACTIVE_TRAFFIC] = context.getResources().getInteger( R.integer.config_wifiFrameworkMinPacketPerSecondActiveTraffic); mVal.pps[HIGH_TRAFFIC] = context.getResources().getInteger( @@ -464,11 +467,11 @@ public class ScoringParams { } /* - * Returns the bonus for the network selection candidate score - * for a recently selected network. + * Returns the duration in minutes for a recently selected network + * to be strongly favored. */ - public int getLastSelectionBonus() { - return mVal.lastSelectionBonus; + public int getLastSelectionMinutes() { + return mVal.lastSelectionMinutes; } /** diff --git a/service/java/com/android/server/wifi/ThroughputScorer.java b/service/java/com/android/server/wifi/ThroughputScorer.java index 3d61beebd..216dd858e 100644 --- a/service/java/com/android/server/wifi/ThroughputScorer.java +++ b/service/java/com/android/server/wifi/ThroughputScorer.java @@ -16,6 +16,8 @@ package com.android.server.wifi; +import static com.android.server.wifi.WifiNetworkSelector.NetworkNominator.NOMINATOR_ID_SCORED; + import android.annotation.NonNull; import android.util.Log; @@ -36,6 +38,12 @@ final class ThroughputScorer implements WifiCandidates.CandidateScorer { */ public static final int THROUGHPUT_SCORER_DEFAULT_EXPID = 42330058; + /** + * Base score that is large enough to override all of the other categories. + * This is applied to the last-select network for a limited duration. + */ + public static final int TOP_TIER_BASE_SCORE = 1_000_000; + private final ScoringParams mScoringParams; // config_wifi_framework_RSSI_SCORE_OFFSET @@ -44,6 +52,9 @@ final class ThroughputScorer implements WifiCandidates.CandidateScorer { // config_wifi_framework_RSSI_SCORE_SLOPE public static final int RSSI_SCORE_SLOPE_IS_4 = 4; + public static final int TRUSTED_AWARD = 1000; + public static final int HALF_TRUSTED_AWARD = 1000 / 2; + private static final boolean USE_USER_CONNECT_CHOICE = true; ThroughputScorer(ScoringParams scoringParams) { @@ -65,9 +76,6 @@ final class ThroughputScorer implements WifiCandidates.CandidateScorer { int throughputBonusScore = calculateThroughputBonusScore(candidate); - int lastSelectionBonusScore = (int) - (candidate.getLastSelectionWeight() * mScoringParams.getLastSelectionBonus()); - int currentNetworkBoost = candidate.isCurrentNetwork() ? mScoringParams.getCurrentNetworkBonus() : 0; @@ -82,17 +90,39 @@ final class ThroughputScorer implements WifiCandidates.CandidateScorer { int savedNetworkAward = candidate.isEphemeral() ? 0 : mScoringParams.getSavedNetworkBonus(); - int score = rssiBaseScore + throughputBonusScore + lastSelectionBonusScore - + currentNetworkBoost + securityAward + unmeteredAward + savedNetworkAward; + int trustedAward = TRUSTED_AWARD; + + if (!candidate.isTrusted()) { + savedNetworkAward = 0; // Saved networks are not untrusted, but clear anyway + unmeteredAward = 0; // Ignore metered for untrusted networks + if (candidate.isCarrierOrPrivileged()) { + trustedAward = HALF_TRUSTED_AWARD; + } else if (candidate.getNominatorId() == NOMINATOR_ID_SCORED) { + Log.e(TAG, "ScoredNetworkNominator is not carrier or privileged!"); + trustedAward = 0; + } else { + trustedAward = 0; + } + } + + int score = rssiBaseScore + throughputBonusScore + + currentNetworkBoost + securityAward + unmeteredAward + savedNetworkAward + + trustedAward; + + if (candidate.getLastSelectionWeight() > 0.0) { + // Put a recently-selected network in a tier above everything else, + // but include rssi and throughput contributions for BSSID selection. + score = TOP_TIER_BASE_SCORE + rssiBaseScore + throughputBonusScore; + } if (DBG) { Log.d(TAG, " rssiScore: " + rssiBaseScore + " throughputScore: " + throughputBonusScore - + " lastSelectionBonus: " + lastSelectionBonusScore + " currentNetworkBoost: " + currentNetworkBoost + " securityAward: " + securityAward + " unmeteredAward: " + unmeteredAward + " savedNetworkAward: " + savedNetworkAward + + " trustedAward: " + trustedAward + " final score: " + score); } diff --git a/service/java/com/android/server/wifi/WifiCandidates.java b/service/java/com/android/server/wifi/WifiCandidates.java index d62ef00ca..a264a49a7 100644 --- a/service/java/com/android/server/wifi/WifiCandidates.java +++ b/service/java/com/android/server/wifi/WifiCandidates.java @@ -91,6 +91,10 @@ public class WifiCandidates { */ boolean isTrusted(); /** + * Returns true if suggestion came from a carrier or privileged app. + */ + boolean isCarrierOrPrivileged(); + /** * Returns true for a metered network. */ boolean isMetered(); @@ -151,6 +155,7 @@ public class WifiCandidates { private final boolean mPasspoint; private final boolean mEphemeral; private final boolean mTrusted; + private final boolean mCarrierOrPrivileged; private final int mPredictedThroughputMbps; CandidateImpl(Key key, WifiConfiguration config, @@ -162,6 +167,7 @@ public class WifiCandidates { boolean isCurrentNetwork, boolean isCurrentBssid, boolean isMetered, + boolean isCarrierOrPrivileged, int predictedThroughputMbps) { this.mKey = key; this.mNominatorId = nominatorId; @@ -174,8 +180,9 @@ public class WifiCandidates { this.mIsMetered = isMetered; this.mIsOpenNetwork = WifiConfigurationUtil.isConfigForOpenNetwork(config); this.mPasspoint = config.isPasspoint(); - this.mEphemeral = config.ephemeral; + this.mEphemeral = config.isEphemeral(); this.mTrusted = config.trusted; + this.mCarrierOrPrivileged = isCarrierOrPrivileged; this.mPredictedThroughputMbps = predictedThroughputMbps; } @@ -210,6 +217,11 @@ public class WifiCandidates { } @Override + public boolean isCarrierOrPrivileged() { + return mCarrierOrPrivileged; + } + + @Override public boolean isMetered() { return (mIsMetered); } @@ -253,8 +265,7 @@ public class WifiCandidates { * Accesses statistical information from the score card */ @Override - public WifiScoreCardProto.Signal - getEventStatistics(WifiScoreCardProto.Event event) { + public WifiScoreCardProto.Signal getEventStatistics(WifiScoreCardProto.Event event) { if (mPerBssid == null) return null; WifiScoreCard.PerSignal perSignal = mPerBssid.lookupSignal(event, getFrequency()); if (perSignal == null) return null; @@ -283,6 +294,7 @@ public class WifiCandidates { + (isCurrentNetwork() ? "current, " : "") + (isEphemeral() ? "ephemeral" : "saved") + ", " + (isTrusted() ? "trusted, " : "") + + (isCarrierOrPrivileged() ? "priv, " : "") + (isMetered() ? "metered, " : "") + (isPasspoint() ? "passpoint, " : "") + (isOpenNetwork() ? "open" : "secure") + " }"; @@ -405,6 +417,7 @@ public class WifiCandidates { scanDetail.getScanResult().frequency, lastSelectionWeightBetweenZeroAndOne, isMetered, + false, predictedThroughputMbps); } @@ -431,6 +444,7 @@ public class WifiCandidates { int frequency, double lastSelectionWeightBetweenZeroAndOne, boolean isMetered, + boolean isCarrierOrPrivileged, int predictedThroughputMbps) { Candidate old = mCandidates.get(key); if (old != null) { @@ -451,6 +465,7 @@ public class WifiCandidates { config.networkId == mCurrentNetworkId, key.bssid.equals(mCurrentBssid), isMetered, + isCarrierOrPrivileged, predictedThroughputMbps); mCandidates.put(key, candidate); return true; @@ -600,5 +615,4 @@ public class WifiCandidates { private boolean mPicky = false; private RuntimeException mLastFault = null; private int mFaultCount = 0; - } diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java index d0a97f574..f6178f24c 100644 --- a/service/java/com/android/server/wifi/WifiNetworkSelector.java +++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java @@ -27,6 +27,7 @@ import android.net.wifi.ScanResult; import android.net.wifi.SupplicantState; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; +import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; @@ -49,6 +50,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** @@ -69,15 +71,6 @@ public class WifiNetworkSelector { public static final int MINIMUM_NETWORK_SELECTION_INTERVAL_MS = 10 * 1000; /** - * Time that it takes for the boost given to the most recently user-selected - * network to decay to zero. - * - * In milliseconds. - */ - @VisibleForTesting - public static final int LAST_USER_SELECTION_DECAY_TO_ZERO_MS = 8 * 60 * 60 * 1000; - - /** * Connected score value used to decide whether a still-connected wifi should be treated * as unconnected when filtering scan results. */ @@ -762,14 +755,10 @@ public class WifiNetworkSelector { return null; } - // Determine the weight for the last user selection - final int lastUserSelectedNetworkId = mWifiConfigManager.getLastSelectedNetwork(); - final double lastSelectionWeight = calculateLastSelectionWeight(); - WifiCandidates wifiCandidates = new WifiCandidates(mWifiScoreCard, mContext); if (currentNetwork != null) { wifiCandidates.setCurrent(currentNetwork.networkId, currentBssid); - // We always want the current network to be a candidate so that it can particpate. + // We always want the current network to be a candidate so that it can participate. // It may also get re-added by a nominator, in which case this fallback // will be replaced. MacAddress bssid = MacAddress.fromString(currentBssid); @@ -780,8 +769,9 @@ public class WifiNetworkSelector { NetworkNominator.NOMINATOR_ID_CURRENT, wifiInfo.getRssi(), wifiInfo.getFrequency(), - lastSelectionWeight, + calculateLastSelectionWeight(currentNetwork.networkId), WifiConfiguration.isMetered(currentNetwork, wifiInfo), + isFromCarrierOrPrivilegedApp(currentNetwork), 0 /* Mbps */); } for (NetworkNominator registeredNominator : mNominators) { @@ -794,13 +784,14 @@ public class WifiNetworkSelector { scanDetail, config); if (key != null) { boolean metered = isEverMetered(config, wifiInfo); + // TODO(b/151981920) Saved passpoint candidates are marked ephemeral boolean added = wifiCandidates.add(key, config, registeredNominator.getId(), scanDetail.getScanResult().level, scanDetail.getScanResult().frequency, - (config.networkId == lastUserSelectedNetworkId) - ? lastSelectionWeight : 0.0, + calculateLastSelectionWeight(config.networkId), metered, + isFromCarrierOrPrivilegedApp(config), predictThroughput(scanDetail)); if (added) { mConnectableNetworks.add(Pair.create(scanDetail, config)); @@ -959,16 +950,14 @@ public class WifiNetworkSelector { } } - private double calculateLastSelectionWeight() { - final int lastUserSelectedNetworkId = mWifiConfigManager.getLastSelectedNetwork(); - double lastSelectionWeight = 0.0; - if (lastUserSelectedNetworkId != WifiConfiguration.INVALID_NETWORK_ID) { - double timeDifference = mClock.getElapsedSinceBootMillis() - - mWifiConfigManager.getLastSelectedTimeStamp(); - double unclipped = 1.0 - (timeDifference / LAST_USER_SELECTION_DECAY_TO_ZERO_MS); - lastSelectionWeight = Math.min(Math.max(unclipped, 0.0), 1.0); - } - return lastSelectionWeight; + private double calculateLastSelectionWeight(int networkId) { + if (networkId != mWifiConfigManager.getLastSelectedNetwork()) return 0.0; + double timeDifference = mClock.getElapsedSinceBootMillis() + - mWifiConfigManager.getLastSelectedTimeStamp(); + long millis = TimeUnit.MINUTES.toMillis(mScoringParams.getLastSelectionMinutes()); + if (timeDifference >= millis) return 0.0; + double unclipped = 1.0 - (timeDifference / millis); + return Math.min(Math.max(unclipped, 0.0), 1.0); } private WifiCandidates.CandidateScorer getActiveCandidateScorer() { @@ -1045,6 +1034,21 @@ public class WifiNetworkSelector { } } + private static boolean isFromCarrierOrPrivilegedApp(WifiConfiguration config) { + if (config.fromWifiNetworkSuggestion + && config.carrierId == TelephonyManager.UNKNOWN_CARRIER_ID) { + // Privileged carrier suggestion + return true; + } + if (config.isEphemeral() + && !config.fromWifiNetworkSpecifier + && !config.fromWifiNetworkSuggestion) { + // From ScoredNetworkNominator + return true; + } + return false; + } + /** * Derives a numeric experiment identifier from a CandidateScorer's identifier. * diff --git a/service/res/values/config.xml b/service/res/values/config.xml index a6d9481c8..76741b121 100644 --- a/service/res/values/config.xml +++ b/service/res/values/config.xml @@ -93,9 +93,8 @@ <integer translatable="false" name="config_wifiFrameworkCurrentNetworkBonus">20</integer> <integer translatable="false" name="config_wifiFrameworkSecureNetworkBonus">10</integer> - <!-- The bonus for the last-selected network starts out very large to override the category - boundaries. --> - <integer translatable="false" name="config_wifiFrameworkLastSelectionBonus">1999</integer> + <!-- The duration in minutes to strongly favor the last-selected network over other options. --> + <integer translatable="false" name="config_wifiFrameworkLastSelectionMinutes">480</integer> <!-- Integer specifying the min packet Tx/Rx rates in packets per second to be considered active traffic so that network selection and scan could be skipped--> diff --git a/service/res/values/overlayable.xml b/service/res/values/overlayable.xml index f88defc43..ff7320016 100644 --- a/service/res/values/overlayable.xml +++ b/service/res/values/overlayable.xml @@ -38,7 +38,7 @@ <item type="integer" name="config_wifiFrameworkUnmeteredNetworkBonus" /> <item type="integer" name="config_wifiFrameworkCurrentNetworkBonus" /> <item type="integer" name="config_wifiFrameworkSecureNetworkBonus" /> - <item type="integer" name="config_wifiFrameworkLastSelectionBonus" /> + <item type="integer" name="config_wifiFrameworkLastSelectionMinutes" /> <item type="integer" name="config_wifiFrameworkMinPacketPerSecondActiveTraffic" /> <item type="integer" name="config_wifiFrameworkMinPacketPerSecondHighTraffic" /> <item type="integer" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz" /> diff --git a/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java b/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java index 0512307c8..918e9e834 100644 --- a/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java @@ -17,6 +17,7 @@ package com.android.server.wifi; import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.lessThan; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; @@ -178,6 +179,27 @@ public class CandidateScorerTest extends WifiBaseTest { } /** + * Prefer to switch with a larger rssi difference. + */ + @Test + public void testSwitchWithLargerDifference() throws Exception { + assertThat(evaluate(mCandidate1.setScanRssi(-80) + .setCurrentNetwork(true)), + lessThan(evaluate(mCandidate2.setScanRssi(-60)))); + } + + /** + * Stay on recently selected network. + */ + @Test + public void testStayOnRecentlySelected() throws Exception { + assertThat(evaluate(mCandidate1.setScanRssi(-80) + .setCurrentNetwork(true) + .setLastSelectionWeight(0.25)), + greaterThan(evaluate(mCandidate2.setScanRssi(-60)))); + } + + /** * Above saturation, don't switch from current even with a large rssi difference. */ @Test @@ -189,7 +211,7 @@ public class CandidateScorerTest extends WifiBaseTest { } /** - * Prefer high throughput network + * Prefer high throughput network. */ @Test public void testPreferHighThroughputNetwork() throws Exception { @@ -200,4 +222,59 @@ public class CandidateScorerTest extends WifiBaseTest { .setPredictedThroughputMbps(50)))); } } + + /** + * Prefer saved over suggestion. + */ + @Test + public void testPreferSavedOverSuggestion() throws Exception { + if (mExpectedExpId != ThroughputScorer.THROUGHPUT_SCORER_DEFAULT_EXPID) return; + assertThat(evaluate(mCandidate1.setScanRssi(-77).setEphemeral(false)), + greaterThan(evaluate(mCandidate2.setScanRssi(-40) + .setEphemeral(true) + .setPredictedThroughputMbps(1000)))); + } + + /** + * Prefer metered saved over unmetered suggestion. + */ + @Test + public void testPreferMeteredSavedOverUnmeteredSuggestion() throws Exception { + if (mExpectedExpId != ThroughputScorer.THROUGHPUT_SCORER_DEFAULT_EXPID) return; + assertThat(evaluate(mCandidate1.setScanRssi(-77).setEphemeral(false).setMetered(false)), + greaterThan(evaluate(mCandidate2.setScanRssi(-40) + .setEphemeral(true) + .setMetered(true) + .setPredictedThroughputMbps(1000)))); + } + + /** + * Prefer trusted metered suggestion over privileged untrusted. + */ + @Test + public void testPreferTrustedOverUntrusted() throws Exception { + if (mExpectedExpId != ThroughputScorer.THROUGHPUT_SCORER_DEFAULT_EXPID) return; + assertThat(evaluate(mCandidate1.setScanRssi(-77).setEphemeral(true).setMetered(true)), + greaterThan(evaluate(mCandidate2.setScanRssi(-40) + .setEphemeral(true) + .setPredictedThroughputMbps(1000) + .setTrusted(false) + .setCarrierOrPrivileged(true)))); + } + + /** + * Prefer carrier untrusted over other untrusted. + */ + @Test + public void testPreferCarrierUntrustedOverOtherUntrusted() throws Exception { + if (mExpectedExpId != ThroughputScorer.THROUGHPUT_SCORER_DEFAULT_EXPID) return; + assertThat(evaluate(mCandidate1.setScanRssi(-77) + .setEphemeral(true) + .setMetered(true) + .setCarrierOrPrivileged(true)), + greaterThan(evaluate(mCandidate2.setScanRssi(-40) + .setPredictedThroughputMbps(1000) + .setTrusted(false)))); + } + } diff --git a/tests/wifitests/src/com/android/server/wifi/ConcreteCandidate.java b/tests/wifitests/src/com/android/server/wifi/ConcreteCandidate.java index cf75ad56c..1d84c4024 100644 --- a/tests/wifitests/src/com/android/server/wifi/ConcreteCandidate.java +++ b/tests/wifitests/src/com/android/server/wifi/ConcreteCandidate.java @@ -30,7 +30,8 @@ public final class ConcreteCandidate implements WifiCandidates.Candidate { private boolean mIsCurrentBssid; private boolean mIsPasspoint; private boolean mIsEphemeral; - private boolean mIsTrusted; + private boolean mIsTrusted = true; + private boolean mCarrierOrPrivileged; private boolean mIsMetered; private int mNominatorId = -1; private double mLastSelectionWeight; @@ -53,6 +54,7 @@ public final class ConcreteCandidate implements WifiCandidates.Candidate { mIsPasspoint = candidate.isPasspoint(); mIsEphemeral = candidate.isEphemeral(); mIsTrusted = candidate.isTrusted(); + mCarrierOrPrivileged = candidate.isCarrierOrPrivileged(); mIsMetered = candidate.isMetered(); mNominatorId = candidate.getNominatorId(); mLastSelectionWeight = candidate.getLastSelectionWeight(); @@ -127,6 +129,16 @@ public final class ConcreteCandidate implements WifiCandidates.Candidate { return mIsTrusted; } + public ConcreteCandidate setCarrierOrPrivileged(boolean carrierOrPrivileged) { + mCarrierOrPrivileged = carrierOrPrivileged; + return this; + } + + @Override + public boolean isCarrierOrPrivileged() { + return mCarrierOrPrivileged; + } + public ConcreteCandidate setMetered(boolean isMetered) { mIsMetered = isMetered; return this; diff --git a/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java b/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java index b97b25248..7ce59c9ee 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java @@ -348,4 +348,24 @@ public class WifiCandidatesTest extends WifiBaseTest { assertEquals(2, mWifiCandidates.size()); assertEquals(0, mWifiCandidates.getFaultCount()); } + + /** + * Verify CarrierOrPrivileged bit is remembered. + */ + @Test + public void testAddCarrierOrPrivilegedCandidate() { + WifiCandidates.Key key = mWifiCandidates + .keyFromScanDetailAndConfig(mScanDetail1, mConfig1); + WifiCandidates.Candidate candidate; + // Make sure the CarrierOrPrivileged false is remembered + assertTrue(mWifiCandidates.add(key, mConfig1, 0, -50, 2412, 0.0, false, false, 100)); + candidate = mWifiCandidates.getCandidates().get(0); + assertFalse(candidate.isCarrierOrPrivileged()); + mWifiCandidates.remove(candidate); + // Make sure the CarrierOrPrivileged true is remembered + assertTrue(mWifiCandidates.add(key, mConfig1, 0, -50, 2412, 0.0, false, true, 100)); + candidate = mWifiCandidates.getCandidates().get(0); + assertTrue(candidate.isCarrierOrPrivileged()); + mWifiCandidates.remove(candidate); + } } |