summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Plass <mplass@google.com>2020-03-05 17:11:53 -0800
committerMichael Plass <mplass@google.com>2020-03-20 14:39:05 -0700
commitc6f842d7676f0a20ca83d3482b5177b528b25503 (patch)
tree08da42de5d2e739d389e10d0cc3832956d5810b7
parent0588d9655753cbc043ecea3f24233be100efecde (diff)
Prefer trusted networks to untrusted
A network marked as untrusted is not used to provide internet, so for network selection it should lose to any trusted candidates. If the suggestion did not come from a carrier or privileged app, rank it even lower. Bug: 148167150 Test: atest com.android.server.wifi Change-Id: Ifc80ff6e81657fb10d3823ccd59724e67fab60f4
-rw-r--r--service/java/com/android/server/wifi/ThroughputScorer.java24
-rw-r--r--service/java/com/android/server/wifi/WifiCandidates.java22
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkSelector.java21
-rw-r--r--tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java55
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ConcreteCandidate.java14
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java20
6 files changed, 149 insertions, 7 deletions
diff --git a/service/java/com/android/server/wifi/ThroughputScorer.java b/service/java/com/android/server/wifi/ThroughputScorer.java
index 020f29dc5..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;
@@ -50,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) {
@@ -85,8 +90,24 @@ final class ThroughputScorer implements WifiCandidates.CandidateScorer {
int savedNetworkAward = candidate.isEphemeral() ? 0 : mScoringParams.getSavedNetworkBonus();
+ 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;
+ + currentNetworkBoost + securityAward + unmeteredAward + savedNetworkAward
+ + trustedAward;
if (candidate.getLastSelectionWeight() > 0.0) {
// Put a recently-selected network in a tier above everything else,
@@ -101,6 +122,7 @@ final class ThroughputScorer implements WifiCandidates.CandidateScorer {
+ " 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 c5f85d05e..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;
@@ -757,7 +758,7 @@ public class WifiNetworkSelector {
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);
@@ -770,6 +771,7 @@ public class WifiNetworkSelector {
wifiInfo.getFrequency(),
calculateLastSelectionWeight(currentNetwork.networkId),
WifiConfiguration.isMetered(currentNetwork, wifiInfo),
+ isFromCarrierOrPrivilegedApp(currentNetwork),
0 /* Mbps */);
}
for (NetworkNominator registeredNominator : mNominators) {
@@ -782,12 +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,
calculateLastSelectionWeight(config.networkId),
metered,
+ isFromCarrierOrPrivilegedApp(config),
predictThroughput(scanDetail));
if (added) {
mConnectableNetworks.add(Pair.create(scanDetail, config));
@@ -1030,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/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java b/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java
index fd09f30cb..918e9e834 100644
--- a/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/CandidateScorerTest.java
@@ -222,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 4b64f71a6..16889b837 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiCandidatesTest.java
@@ -349,4 +349,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);
+ }
}