diff options
author | David Su <dysu@google.com> | 2019-03-21 20:36:22 -0700 |
---|---|---|
committer | David Su <dysu@google.com> | 2019-03-25 12:02:03 -0700 |
commit | 8046ecc97e403fd8ca355fce983f03e4e6c037c9 (patch) | |
tree | 0a2b3064539d4c2a42091df21bec4e5c74ee7ddc | |
parent | d0c327a079c5a0853e1774b087bad4632bc1cbf2 (diff) | |
download | android_frameworks_opt_net_wifi-8046ecc97e403fd8ca355fce983f03e4e6c037c9.tar.gz android_frameworks_opt_net_wifi-8046ecc97e403fd8ca355fce983f03e4e6c037c9.tar.bz2 android_frameworks_opt_net_wifi-8046ecc97e403fd8ca355fce983f03e4e6c037c9.zip |
Record Nominator ID for all possible nominators
Record Nominator ID for all possible nominators
Bug: 127452844
Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh
Change-Id: Id1dc5d29662ae4268d2c9c0c54438ea3ac0c841c
13 files changed, 254 insertions, 43 deletions
diff --git a/service/java/com/android/server/wifi/AvailableNetworkNotifier.java b/service/java/com/android/server/wifi/AvailableNetworkNotifier.java index c28d52195..7def2f37a 100644 --- a/service/java/com/android/server/wifi/AvailableNetworkNotifier.java +++ b/service/java/com/android/server/wifi/AvailableNetworkNotifier.java @@ -38,6 +38,7 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.Messenger; +import android.os.Process; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; @@ -140,11 +141,18 @@ public class AvailableNetworkNotifier { /** System wide identifier for notification in Notification Manager */ private final int mSystemMessageNotificationId; + /** + * The nominator id for this class, from + * {@link com.android.server.wifi.nano.WifiMetricsProto.ConnectionEvent.ConnectionNominator} + */ + private final int mNominatorId; + public AvailableNetworkNotifier( String tag, String storeDataIdentifier, String toggleSettingsName, int notificationIdentifier, + int nominatorId, Context context, Looper looper, FrameworkFacade framework, @@ -158,6 +166,7 @@ public class AvailableNetworkNotifier { mStoreDataIdentifier = storeDataIdentifier; mToggleSettingsName = toggleSettingsName; mSystemMessageNotificationId = notificationIdentifier; + mNominatorId = nominatorId; mContext = context; mHandler = new Handler(looper); mFrameworkFacade = framework; @@ -425,13 +434,19 @@ public class AvailableNetworkNotifier { "User initiated connection to recommended network: " + "\"" + mRecommendedNetwork.SSID + "\""); WifiConfiguration network = createRecommendedNetworkConfig(mRecommendedNetwork); - Message msg = Message.obtain(); - msg.what = WifiManager.CONNECT_NETWORK; - msg.arg1 = WifiConfiguration.INVALID_NETWORK_ID; - msg.obj = network; - msg.replyTo = mSrcMessenger; - mClientModeImpl.sendMessage(msg); - addNetworkToBlacklist(mRecommendedNetwork.SSID); + + NetworkUpdateResult result = mConfigManager.addOrUpdateNetwork(network, Process.WIFI_UID); + if (result.isSuccess()) { + mWifiMetrics.setNominatorForNetwork(result.netId, mNominatorId); + + Message msg = Message.obtain(); + msg.what = WifiManager.CONNECT_NETWORK; + msg.arg1 = result.netId; + msg.obj = null; + msg.replyTo = mSrcMessenger; + mClientModeImpl.sendMessage(msg); + addNetworkToBlacklist(mRecommendedNetwork.SSID); + } mState = STATE_CONNECTING_IN_NOTIFICATION; mHandler.postDelayed( diff --git a/service/java/com/android/server/wifi/CarrierNetworkNotifier.java b/service/java/com/android/server/wifi/CarrierNetworkNotifier.java index 747cf0760..5af400181 100644 --- a/service/java/com/android/server/wifi/CarrierNetworkNotifier.java +++ b/service/java/com/android/server/wifi/CarrierNetworkNotifier.java @@ -26,7 +26,7 @@ import android.os.Looper; import android.provider.Settings; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; -import com.android.server.wifi.util.ScanResultUtil; +import com.android.server.wifi.nano.WifiMetricsProto; /** * This class handles the "carrier wi-fi network available" notification @@ -50,14 +50,16 @@ public class CarrierNetworkNotifier extends AvailableNetworkNotifier { ClientModeImpl clientModeImpl, ConnectToNetworkNotificationBuilder connectToNetworkNotificationBuilder) { super(TAG, STORE_DATA_IDENTIFIER, TOGGLE_SETTINGS_NAME, - SystemMessage.NOTE_CARRIER_NETWORK_AVAILABLE, context, looper, framework, clock, + SystemMessage.NOTE_CARRIER_NETWORK_AVAILABLE, + WifiMetricsProto.ConnectionEvent.NOMINATOR_CARRIER, + context, looper, framework, clock, wifiMetrics, wifiConfigManager, wifiConfigStore, clientModeImpl, connectToNetworkNotificationBuilder); } @Override WifiConfiguration createRecommendedNetworkConfig(ScanResult recommendedNetwork) { - WifiConfiguration network = ScanResultUtil.createNetworkFromScanResult(recommendedNetwork); + WifiConfiguration network = super.createRecommendedNetworkConfig(recommendedNetwork); int eapMethod = recommendedNetwork.carrierApEapType; if (eapMethod == Eap.SIM || eapMethod == Eap.AKA || eapMethod == Eap.AKA_PRIME) { diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index 7497aaf0c..551817021 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -1172,7 +1172,8 @@ public class ClientModeImpl extends StateMachine { private boolean connectToUserSelectNetwork(int netId, int uid, boolean forceReconnect) { logd("connectToUserSelectNetwork netId " + netId + ", uid " + uid + ", forceReconnect = " + forceReconnect); - if (mWifiConfigManager.getConfiguredNetwork(netId) == null) { + WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(netId); + if (config == null) { loge("connectToUserSelectNetwork Invalid network Id=" + netId); return false; } @@ -1191,6 +1192,10 @@ public class ClientModeImpl extends StateMachine { logi("connectToUserSelectNetwork already connecting/connected=" + netId); } else { mWifiConnectivityManager.prepareForForcedConnection(netId); + if (uid == Process.SYSTEM_UID) { + mWifiMetrics.setNominatorForNetwork(config.networkId, + WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL); + } startConnectToNetwork(netId, uid, SUPPLICANT_BSSID_ANY); } return true; diff --git a/service/java/com/android/server/wifi/OpenNetworkNotifier.java b/service/java/com/android/server/wifi/OpenNetworkNotifier.java index 7f61ed9e4..97f390f39 100644 --- a/service/java/com/android/server/wifi/OpenNetworkNotifier.java +++ b/service/java/com/android/server/wifi/OpenNetworkNotifier.java @@ -21,6 +21,7 @@ import android.os.Looper; import android.provider.Settings; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; +import com.android.server.wifi.nano.WifiMetricsProto; /** * This class handles the "open wi-fi network available" notification @@ -44,7 +45,9 @@ public class OpenNetworkNotifier extends AvailableNetworkNotifier { ClientModeImpl clientModeImpl, ConnectToNetworkNotificationBuilder connectToNetworkNotificationBuilder) { super(TAG, STORE_DATA_IDENTIFIER, TOGGLE_SETTINGS_NAME, - SystemMessage.NOTE_NETWORK_AVAILABLE, context, looper, framework, clock, + SystemMessage.NOTE_NETWORK_AVAILABLE, + WifiMetricsProto.ConnectionEvent.NOMINATOR_OPEN_NETWORK_AVAILABLE, + context, looper, framework, clock, wifiMetrics, wifiConfigManager, wifiConfigStore, clientModeImpl, connectToNetworkNotificationBuilder); } diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java index ccfdbc029..f3a3d1f94 100644 --- a/service/java/com/android/server/wifi/WifiMetrics.java +++ b/service/java/com/android/server/wifi/WifiMetrics.java @@ -373,6 +373,12 @@ public class WifiMetrics { private final CellularLinkLayerStatsCollector mCellularLinkLayerStatsCollector; + /** + * Tracks the nominator for each network (i.e. which entity made the suggestion to connect). + * This object should not be cleared. + */ + private final SparseIntArray mNetworkIdToNominatorId = new SparseIntArray(); + @VisibleForTesting static class NetworkSelectionExperimentResults { public static final int MAX_CHOICES = 10; @@ -644,8 +650,8 @@ public class WifiMetrics { case WifiMetricsProto.ConnectionEvent.NOMINATOR_EXTERNAL_SCORED: sb.append("NOMINATOR_EXTERNAL_SCORED"); break; - case WifiMetricsProto.ConnectionEvent.NOMINATOR_NETREC: - sb.append("NOMINATOR_NETREC"); + case WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER: + sb.append("NOMINATOR_SPECIFIER"); break; case WifiMetricsProto.ConnectionEvent.NOMINATOR_SAVED_USER_CONNECT_CHOICE: sb.append("NOMINATOR_SAVED_USER_CONNECT_CHOICE"); @@ -988,26 +994,9 @@ public class WifiMetrics { mCurrentConnectionEvent.mConnectionEvent.useRandomizedMac = config.macRandomizationSetting == WifiConfiguration.RANDOMIZATION_PERSISTENT; - if (config.fromWifiNetworkSpecifier) { - mCurrentConnectionEvent.mConnectionEvent.connectionNominator = - WifiMetricsProto.ConnectionEvent.NOMINATOR_NETREC; - } else if (config.fromWifiNetworkSuggestion) { - mCurrentConnectionEvent.mConnectionEvent.connectionNominator = - WifiMetricsProto.ConnectionEvent.NOMINATOR_SUGGESTION; - } else if (config.isPasspoint()) { - mCurrentConnectionEvent.mConnectionEvent.connectionNominator = - WifiMetricsProto.ConnectionEvent.NOMINATOR_PASSPOINT; - } else if (!config.trusted) { - mCurrentConnectionEvent.mConnectionEvent.connectionNominator = - WifiMetricsProto.ConnectionEvent.NOMINATOR_EXTERNAL_SCORED; - } else if (!config.ephemeral) { - mCurrentConnectionEvent.mConnectionEvent.connectionNominator = - WifiMetricsProto.ConnectionEvent.NOMINATOR_SAVED; - } else { - // TODO(b/127452844): populate other nominator fields - mCurrentConnectionEvent.mConnectionEvent.connectionNominator = - WifiMetricsProto.ConnectionEvent.NOMINATOR_UNKNOWN; - } + mCurrentConnectionEvent.mConnectionEvent.connectionNominator = + mNetworkIdToNominatorId.get(config.networkId, + WifiMetricsProto.ConnectionEvent.NOMINATOR_UNKNOWN); ScanResult candidate = config.getNetworkSelectionStatus().getCandidate(); if (candidate != null) { // Cache the RSSI of the candidate, as the connection event level is updated @@ -2728,6 +2717,7 @@ public class WifiMetrics { pw.println("mWifiNetworkSuggestionApiLog:\n" + mWifiNetworkSuggestionApiLog); pw.println("mWifiNetworkSuggestionApiMatchSizeHistogram:\n" + mWifiNetworkRequestApiMatchSizeHistogram); + pw.println("mNetworkIdToNominatorId:\n" + mNetworkIdToNominatorId); } } } @@ -4712,4 +4702,17 @@ public class WifiMetrics { } } } + + /** + * Sets the nominator for a network (i.e. which entity made the suggestion to connect) + * @param networkId the ID of the network, from its {@link WifiConfiguration} + * @param nominatorId the entity that made the suggestion to connect to this network, + * from {@link WifiMetricsProto.ConnectionEvent.ConnectionNominator} + */ + public void setNominatorForNetwork(int networkId, int nominatorId) { + synchronized (mLock) { + if (networkId == WifiConfiguration.INVALID_NETWORK_ID) return; + mNetworkIdToNominatorId.put(networkId, nominatorId); + } + } } diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java index 174379e33..2cd2aa4f9 100644 --- a/service/java/com/android/server/wifi/WifiNetworkFactory.java +++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java @@ -56,6 +56,7 @@ import android.util.Log; import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.wifi.nano.WifiMetricsProto; import com.android.server.wifi.util.ExternalCallbackTracker; import com.android.server.wifi.util.ScanResultUtil; import com.android.server.wifi.util.WifiPermissionsUtil; @@ -712,6 +713,9 @@ public class WifiNetworkFactory extends NetworkFactory { // necessary checks when processing CONNECT_NETWORK. int networkId = addNetworkToWifiConfigManager(network); + mWifiMetrics.setNominatorForNetwork(networkId, + WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER); + // Send the connect request to ClientModeImpl. // TODO(b/117601161): Refactor this. Message msg = Message.obtain(); diff --git a/service/java/com/android/server/wifi/WifiNetworkSelector.java b/service/java/com/android/server/wifi/WifiNetworkSelector.java index e7608ed78..84dba358a 100644 --- a/service/java/com/android/server/wifi/WifiNetworkSelector.java +++ b/service/java/com/android/server/wifi/WifiNetworkSelector.java @@ -35,6 +35,7 @@ import android.util.Pair; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; +import com.android.server.wifi.nano.WifiMetricsProto; import com.android.server.wifi.util.ScanResultUtil; import java.lang.annotation.Retention; @@ -575,6 +576,8 @@ public class WifiNetworkSelector { localLog("After user selection adjustment, the final candidate is:" + WifiNetworkSelector.toNetworkString(candidate) + " : " + scanResultCandidate.BSSID); + mWifiMetrics.setNominatorForNetwork(candidate.networkId, + WifiMetricsProto.ConnectionEvent.NOMINATOR_SAVED_USER_CONNECT_CHOICE); } return candidate; } @@ -650,6 +653,8 @@ public class WifiNetworkSelector { wifiCandidates.add(scanDetail, config, registeredEvaluator.getId(), score); } + mWifiMetrics.setNominatorForNetwork(config.networkId, + evaluatorIdToNominatorId(registeredEvaluator.getId())); } }); if (selectedNetwork == null && choice != null) { @@ -750,6 +755,24 @@ public class WifiNetworkSelector { return selectedNetwork; } + private static int evaluatorIdToNominatorId(@NetworkEvaluator.EvaluatorId int evaluatorId) { + switch (evaluatorId) { + case NetworkEvaluator.EVALUATOR_ID_SAVED: + return WifiMetricsProto.ConnectionEvent.NOMINATOR_SAVED; + case NetworkEvaluator.EVALUATOR_ID_SUGGESTION: + return WifiMetricsProto.ConnectionEvent.NOMINATOR_SUGGESTION; + case NetworkEvaluator.EVALUATOR_ID_PASSPOINT: + return WifiMetricsProto.ConnectionEvent.NOMINATOR_PASSPOINT; + case NetworkEvaluator.EVALUATOR_ID_CARRIER: + return WifiMetricsProto.ConnectionEvent.NOMINATOR_CARRIER; + case NetworkEvaluator.EVALUATOR_ID_SCORED: + return WifiMetricsProto.ConnectionEvent.NOMINATOR_EXTERNAL_SCORED; + default: + Log.e(TAG, "UnrecognizedEvaluatorId" + evaluatorId); + return WifiMetricsProto.ConnectionEvent.NOMINATOR_UNKNOWN; + } + } + private static boolean isSameNetworkSelection(WifiConfiguration c1, WifiConfiguration c2) { if (c1 == null && c2 == null) { return true; diff --git a/tests/wifitests/src/com/android/server/wifi/CarrierNetworkNotifierTest.java b/tests/wifitests/src/com/android/server/wifi/CarrierNetworkNotifierTest.java index 34995a780..91a9a5de7 100644 --- a/tests/wifitests/src/com/android/server/wifi/CarrierNetworkNotifierTest.java +++ b/tests/wifitests/src/com/android/server/wifi/CarrierNetworkNotifierTest.java @@ -51,6 +51,7 @@ import android.provider.Settings; import androidx.test.filters.SmallTest; +import com.android.server.wifi.nano.WifiMetricsProto; import com.android.server.wifi.nano.WifiMetricsProto.ConnectToNetworkNotificationAndActionCount; import org.junit.Before; @@ -72,6 +73,7 @@ public class CarrierNetworkNotifierTest { private static final String TEST_SSID_2 = "Test SSID 2"; private static final int MIN_RSSI_LEVEL = -127; private static final String CARRIER_NET_NOTIFIER_TAG = CarrierNetworkNotifier.TAG; + private static final int TEST_NETWORK_ID = 42; @Mock private Context mContext; @Mock private Resources mResources; @@ -127,6 +129,8 @@ public class CarrierNetworkNotifierTest { observerCaptor.capture()); mContentObserver = observerCaptor.getValue(); mNotificationController.handleScreenStateChanged(true); + when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt())) + .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID)); } /** @@ -686,6 +690,9 @@ public class CarrierNetworkNotifierTest { mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_CONNECT_TO_NETWORK)); + verify(mWifiMetrics).setNominatorForNetwork(TEST_NETWORK_ID, + WifiMetricsProto.ConnectionEvent.NOMINATOR_CARRIER); + ArgumentCaptor<Message> connectMessageCaptor = ArgumentCaptor.forClass(Message.class); verify(mClientModeImpl).sendMessage(connectMessageCaptor.capture()); Message connectMessage = connectMessageCaptor.getValue(); diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java index 86fb45f2f..6cea3ae9f 100644 --- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java @@ -1173,6 +1173,30 @@ public class ClientModeImplTest { assertEquals(WifiManager.CONNECT_NETWORK_SUCCEEDED, reply.what); } + /** + * Tests that manual connection to a network (from settings app) logs the correct nominator ID. + */ + @Test + public void testManualConnectNominator() throws Exception { + initializeAndAddNetworkAndVerifySuccess(); + Message msg = Message.obtain(); + msg.what = WifiManager.CONNECT_NETWORK; + msg.arg1 = TEST_NETWORK_ID; + msg.obj = null; + msg.sendingUid = Process.SYSTEM_UID; + + WifiConfiguration config = new WifiConfiguration(); + config.networkId = TEST_NETWORK_ID; + + when(mWifiConfigManager.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(config); + + mCmi.sendMessage(msg); + mLooper.dispatchAll(); + + verify(mWifiMetrics).setNominatorForNetwork(TEST_NETWORK_ID, + WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL); + } + @Test public void testDhcpFailure() throws Exception { initializeAndAddNetworkAndVerifySuccess(); diff --git a/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java b/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java index e165dcf55..5e1e7283c 100644 --- a/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java +++ b/tests/wifitests/src/com/android/server/wifi/OpenNetworkNotifierTest.java @@ -51,6 +51,7 @@ import android.provider.Settings; import androidx.test.filters.SmallTest; +import com.android.server.wifi.nano.WifiMetricsProto; import com.android.server.wifi.nano.WifiMetricsProto.ConnectToNetworkNotificationAndActionCount; import org.junit.Before; @@ -72,6 +73,7 @@ public class OpenNetworkNotifierTest { private static final String TEST_SSID_2 = "Test SSID 2"; private static final int MIN_RSSI_LEVEL = -127; private static final String OPEN_NET_NOTIFIER_TAG = OpenNetworkNotifier.TAG; + private static final int TEST_NETWORK_ID = 42; @Mock private Context mContext; @Mock private Resources mResources; @@ -126,6 +128,8 @@ public class OpenNetworkNotifierTest { observerCaptor.capture()); mContentObserver = observerCaptor.getValue(); mNotificationController.handleScreenStateChanged(true); + when(mWifiConfigManager.addOrUpdateNetwork(any(), anyInt())) + .thenReturn(new NetworkUpdateResult(TEST_NETWORK_ID)); } /** @@ -681,6 +685,9 @@ public class OpenNetworkNotifierTest { mBroadcastReceiver.onReceive(mContext, createIntent(ACTION_CONNECT_TO_NETWORK)); + verify(mWifiMetrics).setNominatorForNetwork(TEST_NETWORK_ID, + WifiMetricsProto.ConnectionEvent.NOMINATOR_OPEN_NETWORK_AVAILABLE); + ArgumentCaptor<Message> connectMessageCaptor = ArgumentCaptor.forClass(Message.class); verify(mClientModeImpl).sendMessage(connectMessageCaptor.capture()); Message connectMessage = connectMessageCaptor.getValue(); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java index dda7fa8f2..8d1e89073 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java @@ -126,6 +126,7 @@ public class WifiMetricsTest { TestLooper mTestLooper; Random mRandom = new Random(); private static final int TEST_WIFI_USABILITY_STATS_LISTENER_IDENTIFIER = 2; + private static final int TEST_NETWORK_ID = 42; @Mock Context mContext; @Mock FrameworkFacade mFacade; @Mock Clock mClock; @@ -1344,6 +1345,10 @@ public class WifiMetricsTest { when(scanDetail.getNetworkDetail()).thenReturn(networkDetail); when(scanDetail.getScanResult()).thenReturn(scanResult); + config.networkId = TEST_NETWORK_ID; + mWifiMetrics.setNominatorForNetwork(TEST_NETWORK_ID, + WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL); + //Create a connection event using only the config mWifiMetrics.startConnectionEvent(config, "Red", WifiMetricsProto.ConnectionEvent.ROAM_NONE); @@ -1375,6 +1380,54 @@ public class WifiMetricsTest { mDecodedProto.connectionEvent[1].routerFingerprint.routerTechnology); assertTrue(mDecodedProto.connectionEvent[0].useRandomizedMac); assertFalse(mDecodedProto.connectionEvent[1].useRandomizedMac); + assertEquals(WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL, + mDecodedProto.connectionEvent[0].connectionNominator); + } + + /** + * Tests that the mapping from networkId to nominatorId is not cleared. + */ + @Test + public void testNetworkToNominatorNotCleared() throws Exception { + //Setup mock configs and scan details + NetworkDetail networkDetail = mock(NetworkDetail.class); + when(networkDetail.getWifiMode()).thenReturn(NETWORK_DETAIL_WIFIMODE); + when(networkDetail.getSSID()).thenReturn(SSID); + when(networkDetail.getDtimInterval()).thenReturn(NETWORK_DETAIL_DTIM); + ScanResult scanResult = mock(ScanResult.class); + scanResult.level = SCAN_RESULT_LEVEL; + WifiConfiguration config = mock(WifiConfiguration.class); + config.SSID = "\"" + SSID + "\""; + config.dtimInterval = CONFIG_DTIM; + config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT; + WifiConfiguration.NetworkSelectionStatus networkSelectionStat = + mock(WifiConfiguration.NetworkSelectionStatus.class); + when(networkSelectionStat.getCandidate()).thenReturn(scanResult); + when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStat); + ScanDetail scanDetail = mock(ScanDetail.class); + when(scanDetail.getNetworkDetail()).thenReturn(networkDetail); + when(scanDetail.getScanResult()).thenReturn(scanResult); + + config.networkId = TEST_NETWORK_ID; + mWifiMetrics.setNominatorForNetwork(TEST_NETWORK_ID, + WifiMetricsProto.ConnectionEvent.NOMINATOR_CARRIER); + + // dump() calls clear() internally + mWifiMetrics.dump(null, new PrintWriter(new StringWriter()), + new String[]{WifiMetrics.PROTO_DUMP_ARG}); + + // Create a connection event using only the config + mWifiMetrics.startConnectionEvent(config, "Red", + WifiMetricsProto.ConnectionEvent.ROAM_NONE); + mWifiMetrics.endConnectionEvent( + WifiMetrics.ConnectionEvent.FAILURE_NONE, + WifiMetricsProto.ConnectionEvent.HLF_NONE, + WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN); + + dumpProtoAndDeserialize(); + + assertEquals(WifiMetricsProto.ConnectionEvent.NOMINATOR_CARRIER, + mDecodedProto.connectionEvent[0].connectionNominator); } /** diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java index 0091ae106..52b2e127b 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java @@ -64,6 +64,7 @@ import android.util.Pair; import com.android.internal.util.AsyncChannel; import com.android.server.wifi.WifiNetworkFactory.AccessPoint; +import com.android.server.wifi.nano.WifiMetricsProto; import com.android.server.wifi.util.ScanResultUtil; import com.android.server.wifi.util.WifiPermissionsUtil; @@ -1046,6 +1047,8 @@ public class WifiNetworkFactoryTest { expectedWifiConfiguration.ephemeral = true; expectedWifiConfiguration.fromWifiNetworkSpecifier = true; WifiConfigurationTestUtil.assertConfigurationEqual(expectedWifiConfiguration, network); + verify(mWifiMetrics).setNominatorForNetwork(anyInt(), + eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER)); ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); verify(mClientModeImpl).sendMessage(messageCaptor.capture()); @@ -1157,6 +1160,8 @@ public class WifiNetworkFactoryTest { expectedWifiConfiguration.ephemeral = true; expectedWifiConfiguration.fromWifiNetworkSpecifier = true; WifiConfigurationTestUtil.assertConfigurationEqual(expectedWifiConfiguration, network); + verify(mWifiMetrics).setNominatorForNetwork(anyInt(), + eq(WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER)); // Verify connection message. ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java index 9cefc2e3b..d59f220d7 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSelectorTest.java @@ -21,6 +21,7 @@ import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_NONE; import static com.android.server.wifi.WifiConfigurationTestUtil.SECURITY_PSK; import static com.android.server.wifi.WifiNetworkSelector.experimentIdFromIdentifier; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @@ -38,11 +39,13 @@ import androidx.test.filters.SmallTest; import com.android.internal.R; import com.android.server.wifi.WifiNetworkSelectorTestUtil.ScanDetailsAndWifiConfigs; +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; import org.mockito.MockitoAnnotations; import org.mockito.Spy; @@ -699,6 +702,14 @@ public class WifiNetworkSelectorTest { WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false); + ArgumentCaptor<Integer> nominatorIdCaptor = ArgumentCaptor.forClass(int.class); + verify(mWifiMetrics, atLeastOnce()).setNominatorForNetwork(eq(candidate.networkId), + nominatorIdCaptor.capture()); + // unknown because DummyEvaluator does not have a nominator ID + // getValue() returns the argument from the *last* call + assertEquals(WifiMetricsProto.ConnectionEvent.NOMINATOR_UNKNOWN, + nominatorIdCaptor.getValue().intValue()); + WifiConfigurationTestUtil.assertConfigurationEqual(networkSelectorChoice, candidate); when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() @@ -710,10 +721,66 @@ public class WifiNetworkSelectorTest { candidate = mWifiNetworkSelector.selectNetwork(scanDetails, blacklist, mWifiInfo, false, true, false); + verify(mWifiMetrics, atLeastOnce()).setNominatorForNetwork(eq(candidate.networkId), + nominatorIdCaptor.capture()); + // getValue() returns the argument from the *last* call + assertEquals(WifiMetricsProto.ConnectionEvent.NOMINATOR_SAVED_USER_CONNECT_CHOICE, + nominatorIdCaptor.getValue().intValue()); WifiConfigurationTestUtil.assertConfigurationEqual(userChoice, candidate); } /** + * Tests when multiple evaluators nominate the same candidate, any one of the nominator IDs is + * acceptable. + */ + @Test + public void testMultipleEvaluatorsSetsNominatorIdCorrectly() { + // first dummy evaluator is registered in setup, returns index 0 + // register a second network evaluator that also returns index 0, but with a different ID + mWifiNetworkSelector.registerNetworkEvaluator(new DummyNetworkEvaluator(0, + WifiNetworkSelector.NetworkEvaluator.EVALUATOR_ID_SCORED)); + // register a third network evaluator that also returns index 0, but with a different ID + mWifiNetworkSelector.registerNetworkEvaluator(new DummyNetworkEvaluator(0, + WifiNetworkSelector.NetworkEvaluator.EVALUATOR_ID_SAVED)); + + String[] ssids = {"\"test1\"", "\"test2\""}; + String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4"}; + int[] freqs = {2437, 5180}; + String[] caps = {"[WPA2-PSK][ESS]", "[WPA2-PSK][ESS]"}; + int[] levels = {mThresholdMinimumRssi2G + RSSI_BUMP, mThresholdMinimumRssi5G + RSSI_BUMP}; + int[] securities = {SECURITY_PSK, SECURITY_PSK}; + + ScanDetailsAndWifiConfigs scanDetailsAndConfigs = + WifiNetworkSelectorTestUtil.setupScanDetailsAndConfigStore(ssids, bssids, + freqs, caps, levels, securities, mWifiConfigManager, mClock); + List<ScanDetail> scanDetails = scanDetailsAndConfigs.getScanDetails(); + HashSet<String> blacklist = new HashSet<>(); + + // DummyEvaluator always selects the first network in the list. + WifiConfiguration networkSelectorChoice = scanDetailsAndConfigs.getWifiConfigs()[0]; + networkSelectorChoice.getNetworkSelectionStatus() + .setSeenInLastQualifiedNetworkSelection(true); + + WifiConfiguration userChoice = scanDetailsAndConfigs.getWifiConfigs()[1]; + userChoice.getNetworkSelectionStatus() + .setCandidate(scanDetailsAndConfigs.getScanDetails().get(1).getScanResult()); + + WifiConfiguration candidate = mWifiNetworkSelector.selectNetwork(scanDetails, + blacklist, mWifiInfo, false, true, false); + + ArgumentCaptor<Integer> nominatorIdCaptor = ArgumentCaptor.forClass(int.class); + verify(mWifiMetrics, atLeastOnce()).setNominatorForNetwork(eq(candidate.networkId), + nominatorIdCaptor.capture()); + + for (int nominatorId : nominatorIdCaptor.getAllValues()) { + assertThat(nominatorId, is(oneOf( + WifiMetricsProto.ConnectionEvent.NOMINATOR_UNKNOWN, + WifiMetricsProto.ConnectionEvent.NOMINATOR_EXTERNAL_SCORED, + WifiMetricsProto.ConnectionEvent.NOMINATOR_SAVED))); + } + } + + /** * Wifi network selector doesn't recommend any network if the currently connected 2.4Ghz * network is high quality and no 5GHz networks are available * @@ -1370,7 +1437,8 @@ public class WifiNetworkSelectorTest { public void testCandidateScorerMetrics_onlyOneScorer() { test2GhzHighQuality5GhzAvailable(); - verifyNoMoreInteractions(mWifiMetrics); + verify(mWifiMetrics, never()).logNetworkSelectionDecision( + anyInt(), anyInt(), anyBoolean(), anyInt()); } /** @@ -1392,8 +1460,6 @@ public class WifiNetworkSelectorTest { // WifiNetworkSelector.selectNetwork() twice verify(mWifiMetrics, times(2)).logNetworkSelectionDecision(compatibilityExpId, WifiNetworkSelector.LEGACY_CANDIDATE_SCORER_EXP_ID, true, 2); - - verifyNoMoreInteractions(mWifiMetrics); } /** @@ -1418,8 +1484,6 @@ public class WifiNetworkSelectorTest { // WifiNetworkSelector.selectNetwork() twice verify(mWifiMetrics, times(2)).logNetworkSelectionDecision( WifiNetworkSelector.LEGACY_CANDIDATE_SCORER_EXP_ID, compatibilityExpId, true, 2); - - verifyNoMoreInteractions(mWifiMetrics); } private static final WifiCandidates.CandidateScorer NULL_SCORER = @@ -1462,8 +1526,6 @@ public class WifiNetworkSelectorTest { // WifiNetworkSelector.selectNetwork() twice verify(mWifiMetrics, times(2)).logNetworkSelectionDecision(nullScorerId, WifiNetworkSelector.LEGACY_CANDIDATE_SCORER_EXP_ID, false, 2); - - verifyNoMoreInteractions(mWifiMetrics); } /** @@ -1522,8 +1584,6 @@ public class WifiNetworkSelectorTest { verify(mWifiMetrics, times(2)).logNetworkSelectionDecision( WifiNetworkSelector.LEGACY_CANDIDATE_SCORER_EXP_ID, compatibilityExpId, true, 2); - - verifyNoMoreInteractions(mWifiMetrics); } } |