diff options
-rw-r--r-- | service/java/com/android/server/wifi/WifiNetworkSelector.java | 137 | ||||
-rw-r--r-- | tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java | 46 |
2 files changed, 106 insertions, 77 deletions
diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java index 0cb4dc055..a96f457bd 100644 --- a/service/java/com/android/server/wifi/WifiNetworkSelector.java +++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java @@ -80,6 +80,11 @@ public class WifiNetworkSelector { public static final int WIFI_POOR_SCORE = ConnectedScore.WIFI_TRANSITION_SCORE - 10; /** + * The identifier string of the CandidateScorer to use (in the absence of overrides). + */ + public static final String PRESET_CANDIDATE_SCORER_NAME = null; + + /** * Experiment ID for the legacy scorer. */ public static final int LEGACY_CANDIDATE_SCORER_EXP_ID = 0; @@ -718,61 +723,60 @@ public class WifiNetworkSelector { } } - boolean legacyOverrideWanted = true; + ArrayMap<Integer, Integer> experimentNetworkSelections = new ArrayMap<>(); // for metrics - // Run any (experimental) CandidateScorers we have - try { - int activeExperimentId = LEGACY_CANDIDATE_SCORER_EXP_ID; // default legacy - ArrayMap<Integer, WifiConfiguration> experimentNetworkSelections = new ArrayMap<>(); - experimentNetworkSelections.put(activeExperimentId, selectedNetwork); + final int legacySelectedNetworkId = selectedNetwork == null + ? WifiConfiguration.INVALID_NETWORK_ID + : selectedNetwork.networkId; - for (WifiCandidates.CandidateScorer candidateScorer : mCandidateScorers.values()) { - String id = candidateScorer.getIdentifier(); - int expid = experimentIdFromIdentifier(id); - WifiCandidates.ScoredCandidate choice = wifiCandidates.choose(candidateScorer); - if (choice.candidateKey != null) { - boolean thisOne = (expid == mScoringParams.getExperimentIdentifier()); - localLog(id + (thisOne ? " chooses " : " would choose ") - + choice.candidateKey.networkId - + " score " + choice.value + "+/-" + choice.err - + " expid " + expid); - int networkId = choice.candidateKey.networkId; - WifiConfiguration thisSelectedNetwork = - mWifiConfigManager.getConfiguredNetwork(networkId); - experimentNetworkSelections.put(expid, thisSelectedNetwork); - if (thisOne) { // update selected network only if this experiment is active - activeExperimentId = expid; // ensures that experiment id actually exists - selectedNetwork = thisSelectedNetwork; - legacyOverrideWanted = candidateScorer.userConnectChoiceOverrideWanted(); - Log.i(TAG, id + " chooses " + networkId); - } - } else { - localLog(candidateScorer.getIdentifier() + " found no candidates"); - experimentNetworkSelections.put(expid, null); - } - } + int selectedNetworkId = legacySelectedNetworkId; - for (Map.Entry<Integer, WifiConfiguration> entry : - experimentNetworkSelections.entrySet()) { - int experimentId = entry.getKey(); - if (experimentId == activeExperimentId) continue; - WifiConfiguration thisSelectedNetwork = entry.getValue(); - mWifiMetrics.logNetworkSelectionDecision(experimentId, activeExperimentId, - isSameNetworkSelection(selectedNetwork, thisSelectedNetwork), - groupedCandidates.size()); + // Run all the CandidateScorers + boolean legacyOverrideWanted = true; + final WifiCandidates.CandidateScorer activeScorer = getActiveCandidateScorer(); + for (WifiCandidates.CandidateScorer candidateScorer : mCandidateScorers.values()) { + WifiCandidates.ScoredCandidate choice; + try { + choice = wifiCandidates.choose(candidateScorer); + } catch (RuntimeException e) { + Log.wtf(TAG, "Exception running a CandidateScorer", e); + continue; } - } catch (RuntimeException e) { - Log.wtf(TAG, "Exception running a CandidateScorer, disabling", e); - mCandidateScorers.clear(); - } - - if (selectedNetwork != null) { - // Update the copy of WifiConfiguration to reflect the scan result candidate update - // above. - selectedNetwork = mWifiConfigManager.getConfiguredNetwork(selectedNetwork.networkId); - if (selectedNetwork != null && legacyOverrideWanted) { - selectedNetwork = overrideCandidateWithUserConnectChoice(selectedNetwork); + int networkId = choice.candidateKey == null + ? WifiConfiguration.INVALID_NETWORK_ID + : choice.candidateKey.networkId; + String chooses = " would choose "; + if (candidateScorer == activeScorer) { + chooses = " chooses "; + legacyOverrideWanted = candidateScorer.userConnectChoiceOverrideWanted(); + selectedNetworkId = networkId; } + String id = candidateScorer.getIdentifier(); + int expid = experimentIdFromIdentifier(id); + localLog(id + chooses + networkId + + " score " + choice.value + "+/-" + choice.err + + " expid " + expid); + experimentNetworkSelections.put(expid, networkId); + } + + // Update metrics about differences in the selections made by various methods + final int activeExperimentId = activeScorer == null ? LEGACY_CANDIDATE_SCORER_EXP_ID + : experimentIdFromIdentifier(activeScorer.getIdentifier()); + experimentNetworkSelections.put(LEGACY_CANDIDATE_SCORER_EXP_ID, legacySelectedNetworkId); + for (Map.Entry<Integer, Integer> entry : + experimentNetworkSelections.entrySet()) { + int experimentId = entry.getKey(); + if (experimentId == activeExperimentId) continue; + int thisSelectedNetworkId = entry.getValue(); + mWifiMetrics.logNetworkSelectionDecision(experimentId, activeExperimentId, + selectedNetworkId == thisSelectedNetworkId, + groupedCandidates.size()); + } + + // Get a fresh copy of WifiConfiguration reflecting any scan result updates + selectedNetwork = mWifiConfigManager.getConfiguredNetwork(selectedNetworkId); + if (selectedNetwork != null && legacyOverrideWanted) { + selectedNetwork = overrideCandidateWithUserConnectChoice(selectedNetwork); mLastNetworkSelectionTimeStamp = mClock.getElapsedSinceBootMillis(); } return selectedNetwork; @@ -796,18 +800,6 @@ public class WifiNetworkSelector { } } - private static boolean isSameNetworkSelection(WifiConfiguration c1, WifiConfiguration c2) { - if (c1 == null && c2 == null) { - return true; - } else if (c1 == null && c2 != null) { - return false; - } else if (c1 != null && c2 == null) { - return false; - } else { - return c1.networkId == c2.networkId; - } - } - private double calculateLastSelectionWeight() { final int lastUserSelectedNetworkId = mWifiConfigManager.getLastSelectedNetwork(); double lastSelectionWeight = 0.0; @@ -820,6 +812,24 @@ public class WifiNetworkSelector { return lastSelectionWeight; } + private WifiCandidates.CandidateScorer getActiveCandidateScorer() { + WifiCandidates.CandidateScorer ans = mCandidateScorers.get(PRESET_CANDIDATE_SCORER_NAME); + int overrideExperimentId = mScoringParams.getExperimentIdentifier(); + if (overrideExperimentId >= MIN_SCORER_EXP_ID) { + for (WifiCandidates.CandidateScorer candidateScorer : mCandidateScorers.values()) { + int expId = experimentIdFromIdentifier(candidateScorer.getIdentifier()); + if (expId == overrideExperimentId) { + ans = candidateScorer; + break; + } + } + } + if (ans == null && PRESET_CANDIDATE_SCORER_NAME != null) { + Log.wtf(TAG, PRESET_CANDIDATE_SCORER_NAME + " is not registered!"); + } + return ans; + } + /** * Register a network evaluator * @@ -853,7 +863,7 @@ public class WifiNetworkSelector { } /** - * Derives a numeric experiment identifer from a CandidateScorer's identifier. + * Derives a numeric experiment identifier from a CandidateScorer's identifier. * * @returns a positive number that starts with the decimal digits ID_PREFIX */ @@ -863,6 +873,7 @@ public class WifiNetworkSelector { } private static final int ID_SUFFIX_MOD = 1_000_000; private static final int ID_PREFIX = 42; + private static final int MIN_SCORER_EXP_ID = ID_PREFIX * ID_SUFFIX_MOD; WifiNetworkSelector(Context context, WifiScoreCard wifiScoreCard, ScoringParams scoringParams, WifiConfigManager configManager, Clock clock, LocalLog localLog, diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java index 538f4ba42..ec79e5749 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java @@ -45,7 +45,6 @@ import com.android.server.wifi.nano.WifiMetricsProto; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; @@ -66,6 +65,7 @@ public class WifiNetworkSelectorTest { private static final int RSSI_BUMP = 1; private static final int DUMMY_EVALUATOR_ID_1 = -2; // lowest index private static final int DUMMY_EVALUATOR_ID_2 = -1; + private static final HashSet<String> EMPTY_BLACKLIST = new HashSet<>(); /** Sets up test. */ @Before @@ -1494,8 +1494,12 @@ public class WifiNetworkSelectorTest { assertEquals(experimentId, mScoringParams.getExperimentIdentifier()); mWifiNetworkSelector.registerCandidateScorer(mCandidateScorer); - test2GhzHighQuality5GhzAvailable(); // calls selectNetwork twice - verify(mCandidateScorer, times(2)).scoreCandidates(any()); + + WifiConfiguration selected = mWifiNetworkSelector.selectNetwork( + setUpTwoNetworks(-35, -40), + EMPTY_BLACKLIST, mWifiInfo, false, true, true); + + verify(mCandidateScorer).scoreCandidates(any()); } /** @@ -1510,11 +1514,11 @@ public class WifiNetworkSelectorTest { } /** - * Tests that metrics are recorded for 2 scorers (legacy and legacy compatibility). + * Tests that metrics are recorded for 2 scorers (legacy and another). */ @Test public void testCandidateScorerMetrics_twoScorers() { - mWifiNetworkSelector.registerCandidateScorer(mCompatibilityScorer); + mWifiNetworkSelector.registerCandidateScorer(mScoreCardBasedScorer); // add a second NetworkEvaluator that returns the second network in the scan list mWifiNetworkSelector.registerNetworkEvaluator( @@ -1522,11 +1526,11 @@ public class WifiNetworkSelectorTest { test2GhzHighQuality5GhzAvailable(); - int compatibilityExpId = experimentIdFromIdentifier(mCompatibilityScorer.getIdentifier()); + int registeredExpId = experimentIdFromIdentifier(mScoreCardBasedScorer.getIdentifier()); // Wanted 2 times since test2GhzHighQuality5GhzAvailable() calls // WifiNetworkSelector.selectNetwork() twice - verify(mWifiMetrics, times(2)).logNetworkSelectionDecision(compatibilityExpId, + verify(mWifiMetrics, times(2)).logNetworkSelectionDecision(registeredExpId, WifiNetworkSelector.LEGACY_CANDIDATE_SCORER_EXP_ID, true, 2); } @@ -1598,10 +1602,9 @@ public class WifiNetworkSelectorTest { /** * Tests that metrics are recorded for 2 scorers (legacy and null) when the active - * candidate scorer returns null. + * candidate scorer returns NONE. */ @Test - @Ignore("TODO Until b/126273496 is resolved") public void testCandidateScorerMetrics_twoScorers_nullActive() { int nullScorerId = experimentIdFromIdentifier(NULL_SCORER.getIdentifier()); @@ -1615,16 +1618,31 @@ public class WifiNetworkSelectorTest { mWifiNetworkSelector.registerNetworkEvaluator( new DummyNetworkEvaluator(1, DUMMY_EVALUATOR_ID_2)); - test2GhzHighQuality5GhzAvailable(); + WifiConfiguration selected = mWifiNetworkSelector.selectNetwork( + setUpTwoNetworks(-35, -40), + EMPTY_BLACKLIST, mWifiInfo, false, true, true); - // Wanted 2 times since test2GhzHighQuality5GhzAvailable() calls - // WifiNetworkSelector.selectNetwork() twice - verify(mWifiMetrics, times(2)).logNetworkSelectionDecision( - WifiNetworkSelector.LEGACY_CANDIDATE_SCORER_EXP_ID, nullScorerId, false, 2); + assertNull(selected); + verify(mWifiMetrics).logNetworkSelectionDecision( + WifiNetworkSelector.LEGACY_CANDIDATE_SCORER_EXP_ID, nullScorerId, false, 2); + verify(mWifiMetrics, atLeastOnce()).setNominatorForNetwork(anyInt(), anyInt()); verifyNoMoreInteractions(mWifiMetrics); } + private List<ScanDetail> setUpTwoNetworks(int rssiNetwork1, int rssiNetwork2) { + String[] ssids = {"\"test1\"", "\"test2\""}; + String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"}; + int[] freqs = {5180, 2437}; + String[] caps = {"[ESS]", "[ESS]"}; + int[] levels = {rssiNetwork1, rssiNetwork2}; + int[] securities = {SECURITY_NONE, SECURITY_NONE}; + ScanDetailsAndWifiConfigs scanDetailsAndConfigs = + WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, + freqs, caps, levels, securities, mWifiConfigManager, mClock); + return scanDetailsAndConfigs.getScanDetails(); + } + /** * Tests that metrics are recorded for 3 scorers (legacy, compat, and null scorer). */ |