Home | History | Annotate | Download | only in wifi
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License
     15  */
     16 package com.android.server.wifi;
     17 
     18 import static org.junit.Assert.assertEquals;
     19 import static org.junit.Assert.assertTrue;
     20 import static org.mockito.Mockito.*;
     21 
     22 import android.net.NetworkAgent;
     23 import android.net.wifi.ScanResult;
     24 import android.net.wifi.SupplicantState;
     25 import android.net.wifi.WifiConfiguration;
     26 import android.net.wifi.WifiManager;
     27 import android.net.wifi.WifiSsid;
     28 import android.os.Handler;
     29 import android.os.test.TestLooper;
     30 import android.test.suitebuilder.annotation.SmallTest;
     31 import android.util.Base64;
     32 
     33 
     34 import com.android.server.wifi.hotspot2.NetworkDetail;
     35 import com.android.server.wifi.nano.WifiMetricsProto;
     36 import com.android.server.wifi.nano.WifiMetricsProto.StaEvent;
     37 
     38 import org.junit.Before;
     39 import org.junit.Test;
     40 import org.mockito.Mock;
     41 import org.mockito.MockitoAnnotations;
     42 
     43 import java.io.ByteArrayOutputStream;
     44 import java.io.FileDescriptor;
     45 import java.io.PrintWriter;
     46 import java.io.StringWriter;
     47 import java.util.ArrayList;
     48 import java.util.BitSet;
     49 import java.util.List;
     50 import java.util.regex.Matcher;
     51 import java.util.regex.Pattern;
     52 
     53 /**
     54  * Unit tests for {@link com.android.server.wifi.WifiMetrics}.
     55  */
     56 @SmallTest
     57 public class WifiMetricsTest {
     58 
     59     WifiMetrics mWifiMetrics;
     60     WifiMetricsProto.WifiLog mDeserializedWifiMetrics;
     61     TestLooper mTestLooper;
     62     @Mock Clock mClock;
     63 
     64     @Before
     65     public void setUp() throws Exception {
     66         MockitoAnnotations.initMocks(this);
     67         mDeserializedWifiMetrics = null;
     68         when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 0);
     69         mTestLooper = new TestLooper();
     70         mWifiMetrics = new WifiMetrics(mClock, mTestLooper.getLooper());
     71     }
     72 
     73     /**
     74      * Test that startConnectionEvent and endConnectionEvent can be called repeatedly and out of
     75      * order. Only tests no exception occurs. Creates 3 ConnectionEvents.
     76      */
     77     @Test
     78     public void startAndEndConnectionEventSucceeds() throws Exception {
     79         //Start and end Connection event
     80         mWifiMetrics.startConnectionEvent(null, "RED",
     81                 WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
     82         mWifiMetrics.endConnectionEvent(
     83                 WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
     84                 WifiMetricsProto.ConnectionEvent.HLF_DHCP);
     85         //end Connection event without starting one
     86         mWifiMetrics.endConnectionEvent(
     87                 WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
     88                 WifiMetricsProto.ConnectionEvent.HLF_DHCP);
     89         //start two ConnectionEvents in a row
     90         mWifiMetrics.startConnectionEvent(null, "BLUE",
     91                 WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
     92         mWifiMetrics.startConnectionEvent(null, "GREEN",
     93                 WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
     94     }
     95 
     96     private static final long TEST_RECORD_DURATION_SEC = 12 * 60 * 60;
     97     private static final long TEST_RECORD_DURATION_MILLIS = TEST_RECORD_DURATION_SEC * 1000;
     98 
     99     /**
    100      * Simulate how dumpsys gets the proto from mWifiMetrics, filter the proto bytes out and
    101      * deserialize them into mDeserializedWifiMetrics
    102      */
    103     public void dumpProtoAndDeserialize() throws Exception {
    104         ByteArrayOutputStream stream = new ByteArrayOutputStream();
    105         PrintWriter writer = new PrintWriter(stream);
    106         String[] args = new String[0];
    107 
    108         when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_RECORD_DURATION_MILLIS);
    109         //Test proto dump, by passing in proto arg option
    110         args = new String[]{WifiMetrics.PROTO_DUMP_ARG};
    111         mWifiMetrics.dump(null, writer, args);
    112         writer.flush();
    113         Pattern pattern = Pattern.compile(
    114                 "(?<=WifiMetrics:\\n)([\\s\\S]*)(?=EndWifiMetrics)");
    115         Matcher matcher = pattern.matcher(stream.toString());
    116         assertTrue("Proto Byte string found in WifiMetrics.dump():\n" + stream.toString(),
    117                 matcher.find());
    118         String protoByteString = matcher.group(1);
    119         byte[] protoBytes = Base64.decode(protoByteString, Base64.DEFAULT);
    120         mDeserializedWifiMetrics = WifiMetricsProto.WifiLog.parseFrom(protoBytes);
    121     }
    122 
    123     /**
    124      * Gets the 'clean dump' proto bytes from mWifiMetrics & deserializes it into
    125      * mDeserializedWifiMetrics
    126      */
    127     public void cleanDumpProtoAndDeserialize() throws Exception {
    128         ByteArrayOutputStream stream = new ByteArrayOutputStream();
    129         PrintWriter writer = new PrintWriter(stream);
    130         String[] args = new String[0];
    131 
    132         when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_RECORD_DURATION_MILLIS);
    133         //Test proto dump, by passing in proto arg option
    134         args = new String[]{WifiMetrics.PROTO_DUMP_ARG, WifiMetrics.CLEAN_DUMP_ARG};
    135         mWifiMetrics.dump(null, writer, args);
    136         writer.flush();
    137         String protoByteString = stream.toString();
    138         byte[] protoBytes = Base64.decode(protoByteString, Base64.DEFAULT);
    139         mDeserializedWifiMetrics = WifiMetricsProto.WifiLog.parseFrom(protoBytes);
    140     }
    141 
    142     /** Verifies that dump() includes the expected header */
    143     @Test
    144     public void stateDumpIncludesHeader() throws Exception {
    145         assertStringContains(getStateDump(), "WifiMetrics");
    146     }
    147 
    148     /** Verifies that dump() includes correct alert count when there are no alerts. */
    149     @Test
    150     public void stateDumpAlertCountIsCorrectWithNoAlerts() throws Exception {
    151         assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=()");
    152     }
    153 
    154     /** Verifies that dump() includes correct alert count when there is one alert. */
    155     @Test
    156     public void stateDumpAlertCountIsCorrectWithOneAlert() throws Exception {
    157         mWifiMetrics.incrementAlertReasonCount(1);
    158         assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=(1,1)");
    159     }
    160 
    161     /** Verifies that dump() includes correct alert count when there are multiple alerts. */
    162     @Test
    163     public void stateDumpAlertCountIsCorrectWithMultipleAlerts() throws Exception {
    164         mWifiMetrics.incrementAlertReasonCount(1);
    165         mWifiMetrics.incrementAlertReasonCount(1);
    166         mWifiMetrics.incrementAlertReasonCount(16);
    167         assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=(1,2),(16,1)");
    168     }
    169 
    170     @Test
    171     public void testDumpProtoAndDeserialize() throws Exception {
    172         setAndIncrementMetrics();
    173         dumpProtoAndDeserialize();
    174         assertDeserializedMetricsCorrect();
    175     }
    176 
    177     private static final int NUM_OPEN_NETWORKS = 2;
    178     private static final int NUM_PERSONAL_NETWORKS = 3;
    179     private static final int NUM_ENTERPRISE_NETWORKS = 5;
    180     private static final int NUM_SAVED_NETWORKS = NUM_OPEN_NETWORKS + NUM_PERSONAL_NETWORKS
    181             + NUM_ENTERPRISE_NETWORKS;
    182     private static final int NUM_HIDDEN_NETWORKS = NUM_OPEN_NETWORKS;
    183     private static final int NUM_PASSPOINT_NETWORKS = NUM_ENTERPRISE_NETWORKS;
    184     private static final int NUM_NETWORKS_ADDED_BY_USER = 1;
    185     private static final int NUM_NETWORKS_ADDED_BY_APPS = NUM_SAVED_NETWORKS
    186             - NUM_NETWORKS_ADDED_BY_USER;
    187     private static final boolean TEST_VAL_IS_LOCATION_ENABLED = true;
    188     private static final boolean IS_SCANNING_ALWAYS_ENABLED = true;
    189     private static final int NUM_EMPTY_SCAN_RESULTS = 19;
    190     private static final int NUM_NON_EMPTY_SCAN_RESULTS = 23;
    191     private static final int NUM_SCAN_UNKNOWN = 1;
    192     private static final int NUM_SCAN_SUCCESS = 2;
    193     private static final int NUM_SCAN_FAILURE_INTERRUPTED = 3;
    194     private static final int NUM_SCAN_FAILURE_INVALID_CONFIGURATION = 5;
    195     private static final int NUM_WIFI_UNKNOWN_SCREEN_OFF = 3;
    196     private static final int NUM_WIFI_UNKNOWN_SCREEN_ON = 5;
    197     private static final int NUM_WIFI_ASSOCIATED_SCREEN_OFF = 7;
    198     private static final int NUM_WIFI_ASSOCIATED_SCREEN_ON = 11;
    199     private static final int NUM_CONNECTIVITY_WATCHDOG_PNO_GOOD = 11;
    200     private static final int NUM_CONNECTIVITY_WATCHDOG_PNO_BAD = 12;
    201     private static final int NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_GOOD = 13;
    202     private static final int NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_BAD = 14;
    203     private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS = 1;
    204     private static final int NUM_LAST_RESORT_WATCHDOG_BAD_ASSOCIATION_NETWORKS_TOTAL = 2;
    205     private static final int NUM_LAST_RESORT_WATCHDOG_BAD_AUTHENTICATION_NETWORKS_TOTAL = 3;
    206     private static final int NUM_LAST_RESORT_WATCHDOG_BAD_DHCP_NETWORKS_TOTAL = 4;
    207     private static final int NUM_LAST_RESORT_WATCHDOG_BAD_OTHER_NETWORKS_TOTAL = 5;
    208     private static final int NUM_LAST_RESORT_WATCHDOG_AVAILABLE_NETWORKS_TOTAL = 6;
    209     private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_ASSOCIATION = 7;
    210     private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_AUTHENTICATION = 8;
    211     private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_DHCP = 9;
    212     private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_OTHER = 10;
    213     private static final int NUM_LAST_RESORT_WATCHDOG_SUCCESSES = 5;
    214     private static final int NUM_RSSI_LEVELS_TO_INCREMENT = 20;
    215     private static final int FIRST_RSSI_LEVEL = -80;
    216     private static final int NUM_OPEN_NETWORK_SCAN_RESULTS = 1;
    217     private static final int NUM_PERSONAL_NETWORK_SCAN_RESULTS = 4;
    218     private static final int NUM_ENTERPRISE_NETWORK_SCAN_RESULTS = 3;
    219     private static final int NUM_HIDDEN_NETWORK_SCAN_RESULTS = 1;
    220     private static final int NUM_HOTSPOT2_R1_NETWORK_SCAN_RESULTS = 1;
    221     private static final int NUM_HOTSPOT2_R2_NETWORK_SCAN_RESULTS = 2;
    222     private static final int NUM_SCANS = 5;
    223     private static final int NUM_TOTAL_SCAN_RESULTS = 8;
    224     private static final int MIN_RSSI_LEVEL = -127;
    225     private static final int MAX_RSSI_LEVEL = 0;
    226     private static final int WIFI_SCORE_RANGE_MIN = 0;
    227     private static final int NUM_WIFI_SCORES_TO_INCREMENT = 20;
    228     private static final int WIFI_SCORE_RANGE_MAX = 60;
    229     private static final int NUM_OUT_OF_BOUND_ENTRIES = 10;
    230     private static final int MAX_NUM_SOFTAP_RETURN_CODES = 3;
    231     private static final int NUM_SOFTAP_START_SUCCESS = 3;
    232     private static final int NUM_SOFTAP_FAILED_GENERAL_ERROR = 2;
    233     private static final int NUM_SOFTAP_FAILED_NO_CHANNEL = 1;
    234     private static final int NUM_HAL_CRASHES = 11;
    235     private static final int NUM_WIFICOND_CRASHES = 12;
    236     private static final int NUM_WIFI_ON_FAILURE_DUE_TO_HAL = 13;
    237     private static final int NUM_WIFI_ON_FAILURE_DUE_TO_WIFICOND = 14;
    238 
    239     private ScanDetail buildMockScanDetail(boolean hidden, NetworkDetail.HSRelease hSRelease,
    240             String capabilities) {
    241         ScanDetail mockScanDetail = mock(ScanDetail.class);
    242         NetworkDetail mockNetworkDetail = mock(NetworkDetail.class);
    243         ScanResult mockScanResult = mock(ScanResult.class);
    244         when(mockScanDetail.getNetworkDetail()).thenReturn(mockNetworkDetail);
    245         when(mockScanDetail.getScanResult()).thenReturn(mockScanResult);
    246         when(mockNetworkDetail.isHiddenBeaconFrame()).thenReturn(hidden);
    247         when(mockNetworkDetail.getHSRelease()).thenReturn(hSRelease);
    248         mockScanResult.capabilities = capabilities;
    249         return mockScanDetail;
    250     }
    251 
    252     private List<ScanDetail> buildMockScanDetailList() {
    253         List<ScanDetail> mockScanDetails = new ArrayList<ScanDetail>();
    254         mockScanDetails.add(buildMockScanDetail(true, null, "[ESS]"));
    255         mockScanDetails.add(buildMockScanDetail(false, null, "[WPA2-PSK-CCMP][ESS]"));
    256         mockScanDetails.add(buildMockScanDetail(false, null, "[WPA-PSK-CCMP]"));
    257         mockScanDetails.add(buildMockScanDetail(false, null, "[WPA-PSK-CCMP]"));
    258         mockScanDetails.add(buildMockScanDetail(false, null, "[WEP]"));
    259         mockScanDetails.add(buildMockScanDetail(false, NetworkDetail.HSRelease.R2,
    260                 "[WPA-EAP-CCMP]"));
    261         mockScanDetails.add(buildMockScanDetail(false, NetworkDetail.HSRelease.R2,
    262                 "[WPA2-EAP+FT/EAP-CCMP]"));
    263         mockScanDetails.add(buildMockScanDetail(false, NetworkDetail.HSRelease.R1,
    264                 "[WPA-EAP-CCMP]"));
    265         return mockScanDetails;
    266     }
    267 
    268     private List<WifiConfiguration> buildSavedNetworkList() {
    269         List<WifiConfiguration> testSavedNetworks = new ArrayList<WifiConfiguration>();
    270         for (int i = 0; i < NUM_OPEN_NETWORKS; i++) {
    271             testSavedNetworks.add(WifiConfigurationTestUtil.createOpenHiddenNetwork());
    272         }
    273         for (int i = 0; i < NUM_PERSONAL_NETWORKS; i++) {
    274             testSavedNetworks.add(WifiConfigurationTestUtil.createPskNetwork());
    275         }
    276         for (int i = 0; i < NUM_ENTERPRISE_NETWORKS; i++) {
    277             // Passpoint networks are counted in both Passpoint and Enterprise counters
    278             testSavedNetworks.add(WifiConfigurationTestUtil.createPasspointNetwork());
    279         }
    280         testSavedNetworks.get(0).selfAdded = true;
    281         return testSavedNetworks;
    282     }
    283 
    284     /**
    285      * Set simple metrics, increment others
    286      */
    287     public void setAndIncrementMetrics() throws Exception {
    288         mWifiMetrics.updateSavedNetworks(buildSavedNetworkList());
    289         mWifiMetrics.setIsLocationEnabled(TEST_VAL_IS_LOCATION_ENABLED);
    290         mWifiMetrics.setIsScanningAlwaysEnabled(IS_SCANNING_ALWAYS_ENABLED);
    291 
    292         for (int i = 0; i < NUM_EMPTY_SCAN_RESULTS; i++) {
    293             mWifiMetrics.incrementEmptyScanResultCount();
    294         }
    295         for (int i = 0; i < NUM_NON_EMPTY_SCAN_RESULTS; i++) {
    296             mWifiMetrics.incrementNonEmptyScanResultCount();
    297         }
    298         mWifiMetrics.incrementScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_UNKNOWN,
    299                 NUM_SCAN_UNKNOWN);
    300         mWifiMetrics.incrementScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS,
    301                 NUM_SCAN_SUCCESS);
    302         mWifiMetrics.incrementScanReturnEntry(
    303                 WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED,
    304                 NUM_SCAN_FAILURE_INTERRUPTED);
    305         mWifiMetrics.incrementScanReturnEntry(
    306                 WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION,
    307                 NUM_SCAN_FAILURE_INVALID_CONFIGURATION);
    308         for (int i = 0; i < NUM_WIFI_UNKNOWN_SCREEN_OFF; i++) {
    309             mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN,
    310                     false);
    311         }
    312         for (int i = 0; i < NUM_WIFI_UNKNOWN_SCREEN_ON; i++) {
    313             mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN,
    314                     true);
    315         }
    316         for (int i = 0; i < NUM_WIFI_ASSOCIATED_SCREEN_OFF; i++) {
    317             mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED,
    318                     false);
    319         }
    320         for (int i = 0; i < NUM_WIFI_ASSOCIATED_SCREEN_ON; i++) {
    321             mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED,
    322                     true);
    323         }
    324         for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_PNO_GOOD; i++) {
    325             mWifiMetrics.incrementNumConnectivityWatchdogPnoGood();
    326         }
    327         for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_PNO_BAD; i++) {
    328             mWifiMetrics.incrementNumConnectivityWatchdogPnoBad();
    329         }
    330         for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_GOOD; i++) {
    331             mWifiMetrics.incrementNumConnectivityWatchdogBackgroundGood();
    332         }
    333         for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_BAD; i++) {
    334             mWifiMetrics.incrementNumConnectivityWatchdogBackgroundBad();
    335         }
    336         for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS; i++) {
    337             mWifiMetrics.incrementNumLastResortWatchdogTriggers();
    338         }
    339         mWifiMetrics.addCountToNumLastResortWatchdogBadAssociationNetworksTotal(
    340                 NUM_LAST_RESORT_WATCHDOG_BAD_ASSOCIATION_NETWORKS_TOTAL);
    341         mWifiMetrics.addCountToNumLastResortWatchdogBadAuthenticationNetworksTotal(
    342                 NUM_LAST_RESORT_WATCHDOG_BAD_AUTHENTICATION_NETWORKS_TOTAL);
    343         mWifiMetrics.addCountToNumLastResortWatchdogBadDhcpNetworksTotal(
    344                 NUM_LAST_RESORT_WATCHDOG_BAD_DHCP_NETWORKS_TOTAL);
    345         mWifiMetrics.addCountToNumLastResortWatchdogBadOtherNetworksTotal(
    346                 NUM_LAST_RESORT_WATCHDOG_BAD_OTHER_NETWORKS_TOTAL);
    347         mWifiMetrics.addCountToNumLastResortWatchdogAvailableNetworksTotal(
    348                 NUM_LAST_RESORT_WATCHDOG_AVAILABLE_NETWORKS_TOTAL);
    349         for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_ASSOCIATION; i++) {
    350             mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadAssociation();
    351         }
    352         for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_AUTHENTICATION; i++) {
    353             mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadAuthentication();
    354         }
    355         for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_DHCP; i++) {
    356             mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadDhcp();
    357         }
    358         for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_OTHER; i++) {
    359             mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadOther();
    360         }
    361         for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_SUCCESSES; i++) {
    362             mWifiMetrics.incrementNumLastResortWatchdogSuccesses();
    363         }
    364         for (int i = 0; i < NUM_RSSI_LEVELS_TO_INCREMENT; i++) {
    365             for (int j = 0; j <= i; j++) {
    366                 mWifiMetrics.incrementRssiPollRssiCount(MIN_RSSI_LEVEL + i);
    367             }
    368         }
    369         for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
    370             mWifiMetrics.incrementRssiPollRssiCount(MIN_RSSI_LEVEL - i);
    371         }
    372         for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
    373             mWifiMetrics.incrementRssiPollRssiCount(MAX_RSSI_LEVEL + i);
    374         }
    375         // Test alert-reason clamping.
    376         mWifiMetrics.incrementAlertReasonCount(WifiLoggerHal.WIFI_ALERT_REASON_MIN - 1);
    377         mWifiMetrics.incrementAlertReasonCount(WifiLoggerHal.WIFI_ALERT_REASON_MAX + 1);
    378         // Simple cases for alert reason.
    379         mWifiMetrics.incrementAlertReasonCount(1);
    380         mWifiMetrics.incrementAlertReasonCount(1);
    381         mWifiMetrics.incrementAlertReasonCount(1);
    382         mWifiMetrics.incrementAlertReasonCount(2);
    383         List<ScanDetail> mockScanDetails = buildMockScanDetailList();
    384         for (int i = 0; i < NUM_SCANS; i++) {
    385             mWifiMetrics.countScanResults(mockScanDetails);
    386         }
    387         for (int score = WIFI_SCORE_RANGE_MIN; score < NUM_WIFI_SCORES_TO_INCREMENT; score++) {
    388             for (int offset = 0; offset <= score; offset++) {
    389                 mWifiMetrics.incrementWifiScoreCount(WIFI_SCORE_RANGE_MIN + score);
    390             }
    391         }
    392         for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
    393             mWifiMetrics.incrementWifiScoreCount(WIFI_SCORE_RANGE_MIN - i);
    394         }
    395         for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
    396             mWifiMetrics.incrementWifiScoreCount(WIFI_SCORE_RANGE_MAX + i);
    397         }
    398 
    399         // increment soft ap start return codes
    400         for (int i = 0; i < NUM_SOFTAP_START_SUCCESS; i++) {
    401             mWifiMetrics.incrementSoftApStartResult(true, 0);
    402         }
    403         for (int i = 0; i < NUM_SOFTAP_FAILED_GENERAL_ERROR; i++) {
    404             mWifiMetrics.incrementSoftApStartResult(false, WifiManager.SAP_START_FAILURE_GENERAL);
    405         }
    406         for (int i = 0; i < NUM_SOFTAP_FAILED_NO_CHANNEL; i++) {
    407             mWifiMetrics.incrementSoftApStartResult(false,
    408                     WifiManager.SAP_START_FAILURE_NO_CHANNEL);
    409         }
    410         for (int i = 0; i < NUM_HAL_CRASHES; i++) {
    411             mWifiMetrics.incrementNumHalCrashes();
    412         }
    413         for (int i = 0; i < NUM_WIFICOND_CRASHES; i++) {
    414             mWifiMetrics.incrementNumWificondCrashes();
    415         }
    416         for (int i = 0; i < NUM_WIFI_ON_FAILURE_DUE_TO_HAL; i++) {
    417             mWifiMetrics.incrementNumWifiOnFailureDueToHal();
    418         }
    419         for (int i = 0; i < NUM_WIFI_ON_FAILURE_DUE_TO_WIFICOND; i++) {
    420             mWifiMetrics.incrementNumWifiOnFailureDueToWificond();
    421         }
    422     }
    423 
    424     /**
    425      * Assert that values in deserializedWifiMetrics match those set in 'setAndIncrementMetrics'
    426      */
    427     public void assertDeserializedMetricsCorrect() throws Exception {
    428         assertEquals("mDeserializedWifiMetrics.numSavedNetworks == NUM_SAVED_NETWORKS",
    429                 mDeserializedWifiMetrics.numSavedNetworks, NUM_SAVED_NETWORKS);
    430         assertEquals("mDeserializedWifiMetrics.numOpenNetworks == NUM_OPEN_NETWORKS",
    431                 mDeserializedWifiMetrics.numOpenNetworks, NUM_OPEN_NETWORKS);
    432         assertEquals("mDeserializedWifiMetrics.numPersonalNetworks == NUM_PERSONAL_NETWORKS",
    433                 mDeserializedWifiMetrics.numPersonalNetworks, NUM_PERSONAL_NETWORKS);
    434         assertEquals("mDeserializedWifiMetrics.numEnterpriseNetworks "
    435                         + "== NUM_ENTERPRISE_NETWORKS",
    436                 mDeserializedWifiMetrics.numEnterpriseNetworks, NUM_ENTERPRISE_NETWORKS);
    437         assertEquals("mDeserializedWifiMetrics.numNetworksAddedByUser "
    438                         + "== NUM_NETWORKS_ADDED_BY_USER",
    439                 mDeserializedWifiMetrics.numNetworksAddedByUser, NUM_NETWORKS_ADDED_BY_USER);
    440         assertEquals(NUM_HIDDEN_NETWORKS, mDeserializedWifiMetrics.numHiddenNetworks);
    441         assertEquals(NUM_PASSPOINT_NETWORKS, mDeserializedWifiMetrics.numPasspointNetworks);
    442         assertEquals("mDeserializedWifiMetrics.numNetworksAddedByApps "
    443                         + "== NUM_NETWORKS_ADDED_BY_APPS",
    444                 mDeserializedWifiMetrics.numNetworksAddedByApps, NUM_NETWORKS_ADDED_BY_APPS);
    445         assertEquals("mDeserializedWifiMetrics.isLocationEnabled == TEST_VAL_IS_LOCATION_ENABLED",
    446                 mDeserializedWifiMetrics.isLocationEnabled, TEST_VAL_IS_LOCATION_ENABLED);
    447         assertEquals("mDeserializedWifiMetrics.isScanningAlwaysEnabled "
    448                         + "== IS_SCANNING_ALWAYS_ENABLED",
    449                 mDeserializedWifiMetrics.isScanningAlwaysEnabled, IS_SCANNING_ALWAYS_ENABLED);
    450         assertEquals("mDeserializedWifiMetrics.numEmptyScanResults == NUM_EMPTY_SCAN_RESULTS",
    451                 mDeserializedWifiMetrics.numEmptyScanResults, NUM_EMPTY_SCAN_RESULTS);
    452         assertEquals("mDeserializedWifiMetrics.numNonEmptyScanResults == "
    453                         + "NUM_NON_EMPTY_SCAN_RESULTS",
    454                 mDeserializedWifiMetrics.numNonEmptyScanResults, NUM_NON_EMPTY_SCAN_RESULTS);
    455         assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_UNKNOWN,
    456                 NUM_SCAN_UNKNOWN);
    457         assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_SUCCESS,
    458                 NUM_SCAN_SUCCESS);
    459         assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED,
    460                 NUM_SCAN_FAILURE_INTERRUPTED);
    461         assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION,
    462                 NUM_SCAN_FAILURE_INVALID_CONFIGURATION);
    463         assertSystemStateEntryEquals(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, false,
    464                 NUM_WIFI_UNKNOWN_SCREEN_OFF);
    465         assertSystemStateEntryEquals(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, true,
    466                 NUM_WIFI_UNKNOWN_SCREEN_ON);
    467         assertSystemStateEntryEquals(
    468                 WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, false, NUM_WIFI_ASSOCIATED_SCREEN_OFF);
    469         assertSystemStateEntryEquals(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, true,
    470                 NUM_WIFI_ASSOCIATED_SCREEN_ON);
    471         assertEquals(mDeserializedWifiMetrics.numConnectivityWatchdogPnoGood,
    472                 NUM_CONNECTIVITY_WATCHDOG_PNO_GOOD);
    473         assertEquals(mDeserializedWifiMetrics.numConnectivityWatchdogPnoBad,
    474                 NUM_CONNECTIVITY_WATCHDOG_PNO_BAD);
    475         assertEquals(mDeserializedWifiMetrics.numConnectivityWatchdogBackgroundGood,
    476                 NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_GOOD);
    477         assertEquals(mDeserializedWifiMetrics.numConnectivityWatchdogBackgroundBad,
    478                 NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_BAD);
    479         assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS,
    480                 mDeserializedWifiMetrics.numLastResortWatchdogTriggers);
    481         assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_ASSOCIATION_NETWORKS_TOTAL,
    482                 mDeserializedWifiMetrics.numLastResortWatchdogBadAssociationNetworksTotal);
    483         assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_AUTHENTICATION_NETWORKS_TOTAL,
    484                 mDeserializedWifiMetrics.numLastResortWatchdogBadAuthenticationNetworksTotal);
    485         assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_DHCP_NETWORKS_TOTAL,
    486                 mDeserializedWifiMetrics.numLastResortWatchdogBadDhcpNetworksTotal);
    487         assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_OTHER_NETWORKS_TOTAL,
    488                 mDeserializedWifiMetrics.numLastResortWatchdogBadOtherNetworksTotal);
    489         assertEquals(NUM_LAST_RESORT_WATCHDOG_AVAILABLE_NETWORKS_TOTAL,
    490                 mDeserializedWifiMetrics.numLastResortWatchdogAvailableNetworksTotal);
    491         assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_ASSOCIATION,
    492                 mDeserializedWifiMetrics.numLastResortWatchdogTriggersWithBadAssociation);
    493         assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_AUTHENTICATION,
    494                 mDeserializedWifiMetrics.numLastResortWatchdogTriggersWithBadAuthentication);
    495         assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_DHCP,
    496                 mDeserializedWifiMetrics.numLastResortWatchdogTriggersWithBadDhcp);
    497         assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_OTHER,
    498                 mDeserializedWifiMetrics.numLastResortWatchdogTriggersWithBadOther);
    499         assertEquals(NUM_LAST_RESORT_WATCHDOG_SUCCESSES,
    500                 mDeserializedWifiMetrics.numLastResortWatchdogSuccesses);
    501         assertEquals(TEST_RECORD_DURATION_SEC,
    502                 mDeserializedWifiMetrics.recordDurationSec);
    503         for (int i = 0; i < NUM_RSSI_LEVELS_TO_INCREMENT; i++) {
    504             assertEquals(MIN_RSSI_LEVEL + i, mDeserializedWifiMetrics.rssiPollRssiCount[i].rssi);
    505             assertEquals(i + 1, mDeserializedWifiMetrics.rssiPollRssiCount[i].count);
    506         }
    507         StringBuilder sb_rssi = new StringBuilder();
    508         sb_rssi.append("Number of RSSIs = " + mDeserializedWifiMetrics.rssiPollRssiCount.length);
    509         assertTrue(sb_rssi.toString(), (mDeserializedWifiMetrics.rssiPollRssiCount.length
    510                      <= (MAX_RSSI_LEVEL - MIN_RSSI_LEVEL + 1)));
    511         assertEquals(2, mDeserializedWifiMetrics.alertReasonCount[0].count);  // Clamped reasons.
    512         assertEquals(3, mDeserializedWifiMetrics.alertReasonCount[1].count);
    513         assertEquals(1, mDeserializedWifiMetrics.alertReasonCount[2].count);
    514         assertEquals(3, mDeserializedWifiMetrics.alertReasonCount.length);
    515         assertEquals(NUM_TOTAL_SCAN_RESULTS * NUM_SCANS,
    516                 mDeserializedWifiMetrics.numTotalScanResults);
    517         assertEquals(NUM_OPEN_NETWORK_SCAN_RESULTS * NUM_SCANS,
    518                 mDeserializedWifiMetrics.numOpenNetworkScanResults);
    519         assertEquals(NUM_PERSONAL_NETWORK_SCAN_RESULTS * NUM_SCANS,
    520                 mDeserializedWifiMetrics.numPersonalNetworkScanResults);
    521         assertEquals(NUM_ENTERPRISE_NETWORK_SCAN_RESULTS * NUM_SCANS,
    522                 mDeserializedWifiMetrics.numEnterpriseNetworkScanResults);
    523         assertEquals(NUM_HIDDEN_NETWORK_SCAN_RESULTS * NUM_SCANS,
    524                 mDeserializedWifiMetrics.numHiddenNetworkScanResults);
    525         assertEquals(NUM_HOTSPOT2_R1_NETWORK_SCAN_RESULTS * NUM_SCANS,
    526                 mDeserializedWifiMetrics.numHotspot2R1NetworkScanResults);
    527         assertEquals(NUM_HOTSPOT2_R2_NETWORK_SCAN_RESULTS * NUM_SCANS,
    528                 mDeserializedWifiMetrics.numHotspot2R2NetworkScanResults);
    529         assertEquals(NUM_SCANS,
    530                 mDeserializedWifiMetrics.numScans);
    531         for (int score_index = 0; score_index < NUM_WIFI_SCORES_TO_INCREMENT; score_index++) {
    532             assertEquals(WIFI_SCORE_RANGE_MIN + score_index,
    533                     mDeserializedWifiMetrics.wifiScoreCount[score_index].score);
    534             assertEquals(score_index + 1,
    535                     mDeserializedWifiMetrics.wifiScoreCount[score_index].count);
    536         }
    537         StringBuilder sb_wifi_score = new StringBuilder();
    538         sb_wifi_score.append("Number of wifi_scores = "
    539                 + mDeserializedWifiMetrics.wifiScoreCount.length);
    540         assertTrue(sb_wifi_score.toString(), (mDeserializedWifiMetrics.wifiScoreCount.length
    541                 <= (WIFI_SCORE_RANGE_MAX - WIFI_SCORE_RANGE_MIN + 1)));
    542         StringBuilder sb_wifi_limits = new StringBuilder();
    543         sb_wifi_limits.append("Wifi Score limit is " +  NetworkAgent.WIFI_BASE_SCORE
    544                 + ">= " + WIFI_SCORE_RANGE_MAX);
    545         assertTrue(sb_wifi_limits.toString(), NetworkAgent.WIFI_BASE_SCORE <= WIFI_SCORE_RANGE_MAX);
    546         assertEquals(MAX_NUM_SOFTAP_RETURN_CODES, mDeserializedWifiMetrics.softApReturnCode.length);
    547         assertEquals(WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_STARTED_SUCCESSFULLY,
    548                      mDeserializedWifiMetrics.softApReturnCode[0].startResult);
    549         assertEquals(NUM_SOFTAP_START_SUCCESS, mDeserializedWifiMetrics.softApReturnCode[0].count);
    550         assertEquals(WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_GENERAL_ERROR,
    551                      mDeserializedWifiMetrics.softApReturnCode[1].startResult);
    552         assertEquals(NUM_SOFTAP_FAILED_GENERAL_ERROR,
    553                      mDeserializedWifiMetrics.softApReturnCode[1].count);
    554         assertEquals(WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_NO_CHANNEL,
    555                      mDeserializedWifiMetrics.softApReturnCode[2].startResult);
    556         assertEquals(NUM_SOFTAP_FAILED_NO_CHANNEL,
    557                      mDeserializedWifiMetrics.softApReturnCode[2].count);
    558         assertEquals(NUM_HAL_CRASHES, mDeserializedWifiMetrics.numHalCrashes);
    559         assertEquals(NUM_WIFICOND_CRASHES, mDeserializedWifiMetrics.numWificondCrashes);
    560         assertEquals(NUM_WIFI_ON_FAILURE_DUE_TO_HAL,
    561                 mDeserializedWifiMetrics.numWifiOnFailureDueToHal);
    562         assertEquals(NUM_WIFI_ON_FAILURE_DUE_TO_WIFICOND,
    563                 mDeserializedWifiMetrics.numWifiOnFailureDueToWificond);
    564     }
    565 
    566     /**
    567      *  Assert deserialized metrics Scan Return Entry equals count
    568      */
    569     public void assertScanReturnEntryEquals(int returnCode, int count) {
    570         for (int i = 0; i < mDeserializedWifiMetrics.scanReturnEntries.length; i++) {
    571             if (mDeserializedWifiMetrics.scanReturnEntries[i].scanReturnCode == returnCode) {
    572                 assertEquals(mDeserializedWifiMetrics.scanReturnEntries[i].scanResultsCount, count);
    573                 return;
    574             }
    575         }
    576         assertEquals(null, count);
    577     }
    578 
    579     /**
    580      *  Assert deserialized metrics SystemState entry equals count
    581      */
    582     public void assertSystemStateEntryEquals(int state, boolean screenOn, int count) {
    583         for (int i = 0; i < mDeserializedWifiMetrics.wifiSystemStateEntries.length; i++) {
    584             if (mDeserializedWifiMetrics.wifiSystemStateEntries[i].wifiState == state
    585                     && mDeserializedWifiMetrics.wifiSystemStateEntries[i].isScreenOn == screenOn) {
    586                 assertEquals(mDeserializedWifiMetrics.wifiSystemStateEntries[i].wifiStateCount,
    587                         count);
    588                 return;
    589             }
    590         }
    591         assertEquals(null, count);
    592     }
    593     /**
    594      * Combination of all other WifiMetrics unit tests, an internal-integration test, or functional
    595      * test
    596      */
    597     @Test
    598     public void setMetricsSerializeDeserializeAssertMetricsSame() throws Exception {
    599         setAndIncrementMetrics();
    600         startAndEndConnectionEventSucceeds();
    601         dumpProtoAndDeserialize();
    602         assertDeserializedMetricsCorrect();
    603         assertEquals("mDeserializedWifiMetrics.connectionEvent.length",
    604                 2, mDeserializedWifiMetrics.connectionEvent.length);
    605         //<TODO> test individual connectionEvents for correctness,
    606         // check scanReturnEntries & wifiSystemStateEntries counts and individual elements
    607         // pending their implementation</TODO>
    608     }
    609 
    610     private static final String SSID = "red";
    611     private static final int CONFIG_DTIM = 3;
    612     private static final int NETWORK_DETAIL_WIFIMODE = 5;
    613     private static final int NETWORK_DETAIL_DTIM = 7;
    614     private static final int SCAN_RESULT_LEVEL = -30;
    615     /**
    616      * Test that WifiMetrics is correctly getting data from ScanDetail and WifiConfiguration
    617      */
    618     @Test
    619     public void testScanDetailAndWifiConfigurationUsage() throws Exception {
    620         //Setup mock configs and scan details
    621         NetworkDetail networkDetail = mock(NetworkDetail.class);
    622         when(networkDetail.getWifiMode()).thenReturn(NETWORK_DETAIL_WIFIMODE);
    623         when(networkDetail.getSSID()).thenReturn(SSID);
    624         when(networkDetail.getDtimInterval()).thenReturn(NETWORK_DETAIL_DTIM);
    625         ScanResult scanResult = mock(ScanResult.class);
    626         scanResult.level = SCAN_RESULT_LEVEL;
    627         WifiConfiguration config = mock(WifiConfiguration.class);
    628         config.SSID = "\"" + SSID + "\"";
    629         config.dtimInterval = CONFIG_DTIM;
    630         WifiConfiguration.NetworkSelectionStatus networkSelectionStat =
    631                 mock(WifiConfiguration.NetworkSelectionStatus.class);
    632         when(networkSelectionStat.getCandidate()).thenReturn(scanResult);
    633         when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStat);
    634         ScanDetail scanDetail = mock(ScanDetail.class);
    635         when(scanDetail.getNetworkDetail()).thenReturn(networkDetail);
    636         when(scanDetail.getScanResult()).thenReturn(scanResult);
    637 
    638         //Create a connection event using only the config
    639         mWifiMetrics.startConnectionEvent(config, "Red",
    640                 WifiMetricsProto.ConnectionEvent.ROAM_NONE);
    641         mWifiMetrics.endConnectionEvent(
    642                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
    643                 WifiMetricsProto.ConnectionEvent.HLF_NONE);
    644 
    645         //Create a connection event using the config and a scan detail
    646         mWifiMetrics.startConnectionEvent(config, "Green",
    647                 WifiMetricsProto.ConnectionEvent.ROAM_NONE);
    648         mWifiMetrics.setConnectionScanDetail(scanDetail);
    649         mWifiMetrics.endConnectionEvent(
    650                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
    651                 WifiMetricsProto.ConnectionEvent.HLF_NONE);
    652 
    653         //Dump proto from mWifiMetrics and deserialize it to mDeserializedWifiMetrics
    654         dumpProtoAndDeserialize();
    655 
    656         //Check that the correct values are being flowed through
    657         assertEquals(mDeserializedWifiMetrics.connectionEvent.length, 2);
    658         assertEquals(mDeserializedWifiMetrics.connectionEvent[0].routerFingerprint.dtim,
    659                 CONFIG_DTIM);
    660         assertEquals(mDeserializedWifiMetrics.connectionEvent[0].signalStrength, SCAN_RESULT_LEVEL);
    661         assertEquals(mDeserializedWifiMetrics.connectionEvent[1].routerFingerprint.dtim,
    662                 NETWORK_DETAIL_DTIM);
    663         assertEquals(mDeserializedWifiMetrics.connectionEvent[1].signalStrength,
    664                 SCAN_RESULT_LEVEL);
    665         assertEquals(mDeserializedWifiMetrics.connectionEvent[1].routerFingerprint.routerTechnology,
    666                 NETWORK_DETAIL_WIFIMODE);
    667     }
    668 
    669     /**
    670      * Test that WifiMetrics is being cleared after dumping via proto
    671      */
    672     @Test
    673     public void testMetricsClearedAfterProtoRequested() throws Exception {
    674         // Create 3 ConnectionEvents
    675         mWifiMetrics.startConnectionEvent(null, "RED",
    676                 WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
    677         mWifiMetrics.endConnectionEvent(
    678                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
    679                 WifiMetricsProto.ConnectionEvent.HLF_NONE);
    680         mWifiMetrics.startConnectionEvent(null, "YELLOW",
    681                 WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
    682         mWifiMetrics.endConnectionEvent(
    683                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
    684                 WifiMetricsProto.ConnectionEvent.HLF_NONE);
    685         mWifiMetrics.startConnectionEvent(null, "GREEN",
    686                 WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
    687         mWifiMetrics.endConnectionEvent(
    688                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
    689                 WifiMetricsProto.ConnectionEvent.HLF_NONE);
    690         mWifiMetrics.startConnectionEvent(null, "ORANGE",
    691                 WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
    692         mWifiMetrics.endConnectionEvent(
    693                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
    694                 WifiMetricsProto.ConnectionEvent.HLF_NONE);
    695 
    696         //Dump proto and deserialize
    697         //This should clear all the metrics in mWifiMetrics,
    698         dumpProtoAndDeserialize();
    699         //Check there are only 3 connection events
    700         assertEquals(mDeserializedWifiMetrics.connectionEvent.length, 4);
    701         assertEquals(mDeserializedWifiMetrics.rssiPollRssiCount.length, 0);
    702         assertEquals(mDeserializedWifiMetrics.alertReasonCount.length, 0);
    703 
    704         // Create 2 ConnectionEvents
    705         mWifiMetrics.startConnectionEvent(null,  "BLUE",
    706                 WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
    707         mWifiMetrics.endConnectionEvent(
    708                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
    709                 WifiMetricsProto.ConnectionEvent.HLF_NONE);
    710         mWifiMetrics.startConnectionEvent(null, "RED",
    711                 WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
    712         mWifiMetrics.endConnectionEvent(
    713                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
    714                 WifiMetricsProto.ConnectionEvent.HLF_NONE);
    715 
    716         //Dump proto and deserialize
    717         dumpProtoAndDeserialize();
    718         //Check there are only 2 connection events
    719         assertEquals(mDeserializedWifiMetrics.connectionEvent.length, 2);
    720     }
    721 
    722     /**
    723      * Tests that after setting metrics values they can be serialized and deserialized with the
    724      *   $ adb shell dumpsys wifi wifiMetricsProto clean
    725      */
    726     @Test
    727     public void testClearMetricsDump() throws Exception {
    728         setAndIncrementMetrics();
    729         startAndEndConnectionEventSucceeds();
    730         cleanDumpProtoAndDeserialize();
    731         assertDeserializedMetricsCorrect();
    732         assertEquals("mDeserializedWifiMetrics.connectionEvent.length",
    733                 2, mDeserializedWifiMetrics.connectionEvent.length);
    734     }
    735 
    736     private static final int NUM_REPEATED_DELTAS = 7;
    737     private static final int REPEATED_DELTA = 0;
    738     private static final int SINGLE_GOOD_DELTA = 1;
    739     private static final int SINGLE_TIMEOUT_DELTA = 2;
    740     private static final int NUM_REPEATED_BOUND_DELTAS = 2;
    741     private static final int MAX_DELTA_LEVEL = 127;
    742     private static final int MIN_DELTA_LEVEL = -127;
    743     private static final int ARBITRARY_DELTA_LEVEL = 20;
    744 
    745     /**
    746      * Sunny day RSSI delta logging scenario.
    747      * Logs one rssi delta value multiple times
    748      * Logs a different delta value a single time
    749      */
    750     @Test
    751     public void testRssiDeltasSuccessfulLogging() throws Exception {
    752         // Generate some repeated deltas
    753         for (int i = 0; i < NUM_REPEATED_DELTAS; i++) {
    754             generateRssiDelta(MIN_RSSI_LEVEL, REPEATED_DELTA,
    755                     WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
    756         }
    757         // Generate a single delta
    758         generateRssiDelta(MIN_RSSI_LEVEL, SINGLE_GOOD_DELTA,
    759                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
    760         dumpProtoAndDeserialize();
    761         assertEquals(2, mDeserializedWifiMetrics.rssiPollDeltaCount.length);
    762         // Check the repeated deltas
    763         assertEquals(NUM_REPEATED_DELTAS, mDeserializedWifiMetrics.rssiPollDeltaCount[0].count);
    764         assertEquals(REPEATED_DELTA, mDeserializedWifiMetrics.rssiPollDeltaCount[0].rssi);
    765         // Check the single delta
    766         assertEquals(1, mDeserializedWifiMetrics.rssiPollDeltaCount[1].count);
    767         assertEquals(SINGLE_GOOD_DELTA, mDeserializedWifiMetrics.rssiPollDeltaCount[1].rssi);
    768     }
    769 
    770     /**
    771      * Tests that Rssi Delta events whose scanResult and Rssi Poll come too far apart, timeout,
    772      * and are not logged.
    773      */
    774     @Test
    775     public void testRssiDeltasTimeout() throws Exception {
    776         // Create timed out rssi deltas
    777         generateRssiDelta(MIN_RSSI_LEVEL, REPEATED_DELTA,
    778                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS + 1);
    779         generateRssiDelta(MIN_RSSI_LEVEL, SINGLE_TIMEOUT_DELTA,
    780                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS + 1);
    781         dumpProtoAndDeserialize();
    782         assertEquals(0, mDeserializedWifiMetrics.rssiPollDeltaCount.length);
    783     }
    784 
    785     /**
    786      * Tests the exact inclusive boundaries of RSSI delta logging.
    787      */
    788     @Test
    789     public void testRssiDeltaSuccessfulLoggingExactBounds() throws Exception {
    790         generateRssiDelta(MIN_RSSI_LEVEL, MAX_DELTA_LEVEL,
    791                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
    792         generateRssiDelta(MAX_RSSI_LEVEL, MIN_DELTA_LEVEL,
    793                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
    794         dumpProtoAndDeserialize();
    795         assertEquals(2, mDeserializedWifiMetrics.rssiPollDeltaCount.length);
    796         assertEquals(MIN_DELTA_LEVEL, mDeserializedWifiMetrics.rssiPollDeltaCount[0].rssi);
    797         assertEquals(1, mDeserializedWifiMetrics.rssiPollDeltaCount[0].count);
    798         assertEquals(MAX_DELTA_LEVEL, mDeserializedWifiMetrics.rssiPollDeltaCount[1].rssi);
    799         assertEquals(1, mDeserializedWifiMetrics.rssiPollDeltaCount[1].count);
    800     }
    801 
    802     /**
    803      * Tests the exact exclusive boundaries of RSSI delta logging.
    804      * This test ensures that too much data is not generated.
    805      */
    806     @Test
    807     public void testRssiDeltaOutOfBounds() throws Exception {
    808         generateRssiDelta(MIN_RSSI_LEVEL, MAX_DELTA_LEVEL + 1,
    809                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
    810         generateRssiDelta(MAX_RSSI_LEVEL, MIN_DELTA_LEVEL - 1,
    811                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
    812         dumpProtoAndDeserialize();
    813         assertEquals(0, mDeserializedWifiMetrics.rssiPollDeltaCount.length);
    814     }
    815 
    816     /**
    817      * This test ensures no rssi Delta is logged after an unsuccessful ConnectionEvent
    818      */
    819     @Test
    820     public void testUnsuccesfulConnectionEventRssiDeltaIsNotLogged() throws Exception {
    821         generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL,
    822                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS,
    823                 false, // successfulConnectionEvent
    824                 true, // completeConnectionEvent
    825                 true, // useValidScanResult
    826                 true // dontDeserializeBeforePoll
    827         );
    828 
    829         dumpProtoAndDeserialize();
    830         assertEquals(0, mDeserializedWifiMetrics.rssiPollDeltaCount.length);
    831     }
    832 
    833     /**
    834      * This test ensures rssi Deltas can be logged during a ConnectionEvent
    835      */
    836     @Test
    837     public void testIncompleteConnectionEventRssiDeltaIsLogged() throws Exception {
    838         generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL,
    839                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS,
    840                 true, // successfulConnectionEvent
    841                 false, // completeConnectionEvent
    842                 true, // useValidScanResult
    843                 true // dontDeserializeBeforePoll
    844         );
    845         dumpProtoAndDeserialize();
    846         assertEquals(1, mDeserializedWifiMetrics.rssiPollDeltaCount.length);
    847         assertEquals(ARBITRARY_DELTA_LEVEL, mDeserializedWifiMetrics.rssiPollDeltaCount[0].rssi);
    848         assertEquals(1, mDeserializedWifiMetrics.rssiPollDeltaCount[0].count);
    849     }
    850 
    851     /**
    852      * This test ensures that no delta is logged for a null ScanResult Candidate
    853      */
    854     @Test
    855     public void testRssiDeltaNotLoggedForNullCandidateScanResult() throws Exception {
    856         generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL,
    857                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS,
    858                 true, // successfulConnectionEvent
    859                 true, // completeConnectionEvent
    860                 false, // useValidScanResult
    861                 true // dontDeserializeBeforePoll
    862         );
    863         dumpProtoAndDeserialize();
    864         assertEquals(0, mDeserializedWifiMetrics.rssiPollDeltaCount.length);
    865     }
    866 
    867     /**
    868      * This test ensures that Rssi Deltas are not logged over a 'clear()' call (Metrics Serialized)
    869      */
    870     @Test
    871     public void testMetricsSerializedDuringRssiDeltaEventLogsNothing() throws Exception {
    872         generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL,
    873                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS,
    874                 true, // successfulConnectionEvent
    875                 true, // completeConnectionEvent
    876                 true, // useValidScanResult
    877                 false // dontDeserializeBeforePoll
    878         );
    879         dumpProtoAndDeserialize();
    880         assertEquals(0, mDeserializedWifiMetrics.rssiPollDeltaCount.length);
    881     }
    882 
    883     private static final int DEAUTH_REASON = 7;
    884     private static final int ASSOC_STATUS = 11;
    885     private static final int ASSOC_TIMEOUT = 1;
    886     private static final int LOCAL_GEN = 1;
    887     private static final int AUTH_FAILURE_REASON = WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD;
    888     private static final int NUM_TEST_STA_EVENTS = 14;
    889     private static final String   sSSID = "\"SomeTestSsid\"";
    890     private static final WifiSsid sWifiSsid = WifiSsid.createFromAsciiEncoded(sSSID);
    891     private static final String   sBSSID = "01:02:03:04:05:06";
    892 
    893     private final StateChangeResult mStateDisconnected =
    894             new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.DISCONNECTED);
    895     private final StateChangeResult mStateCompleted =
    896             new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED);
    897     // Test bitmasks of supplicant state changes
    898     private final int mSupBm1 = WifiMetrics.supplicantStateToBit(mStateDisconnected.state);
    899     private final int mSupBm2 = WifiMetrics.supplicantStateToBit(mStateDisconnected.state)
    900             | WifiMetrics.supplicantStateToBit(mStateCompleted.state);
    901     // An invalid but interesting wifiConfiguration that exercises the StaEvent.ConfigInfo encoding
    902     private final WifiConfiguration mTestWifiConfig = createComplexWifiConfig();
    903     // <msg.what> <msg.arg1> <msg.arg2>
    904     private int[][] mTestStaMessageInts = {
    905         {WifiMonitor.ASSOCIATION_REJECTION_EVENT,   ASSOC_TIMEOUT,      ASSOC_STATUS},
    906         {WifiMonitor.AUTHENTICATION_FAILURE_EVENT,  0,                  AUTH_FAILURE_REASON},
    907         {WifiMonitor.NETWORK_CONNECTION_EVENT,      0,                  0},
    908         {WifiMonitor.NETWORK_DISCONNECTION_EVENT,   LOCAL_GEN,          DEAUTH_REASON},
    909         {WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0,                  0},
    910         {WifiStateMachine.CMD_ASSOCIATED_BSSID,     0,                  0},
    911         {WifiStateMachine.CMD_TARGET_BSSID,         0,                  0},
    912         {WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0,                  0},
    913         {WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0,                  0}
    914     };
    915     private Object[] mTestStaMessageObjs = {
    916         null,
    917         null,
    918         null,
    919         null,
    920         mStateDisconnected,
    921         null,
    922         null,
    923         mStateDisconnected,
    924         mStateCompleted
    925     };
    926     // Values used to generate the StaEvent log calls from WifiStateMachine
    927     // <StaEvent.Type>, <StaEvent.FrameworkDisconnectReason>, <1|0>(testWifiConfiguration, null)
    928     private int[][] mTestStaLogInts = {
    929         {StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL, 0,                          0},
    930         {StaEvent.TYPE_CMD_IP_CONFIGURATION_LOST,       0,                          0},
    931         {StaEvent.TYPE_CMD_IP_REACHABILITY_LOST,        0,                          0},
    932         {StaEvent.TYPE_CMD_START_CONNECT,               0,                          1},
    933         {StaEvent.TYPE_CMD_START_ROAM,                  0,                          1},
    934         {StaEvent.TYPE_CONNECT_NETWORK,                 0,                          1},
    935         {StaEvent.TYPE_NETWORK_AGENT_VALID_NETWORK,     0,                          0},
    936         {StaEvent.TYPE_FRAMEWORK_DISCONNECT,            StaEvent.DISCONNECT_API,    0}
    937     };
    938     // Values used to generate the StaEvent log calls from WifiMonitor
    939     // <type>, <reason>, <status>, <local_gen>,
    940     // <auth_fail_reason>, <assoc_timed_out> <supplicantStateChangeBitmask> <1|0>(has ConfigInfo)
    941     private int[][] mExpectedValues = {
    942         {StaEvent.TYPE_ASSOCIATION_REJECTION_EVENT,     -1,  ASSOC_STATUS,         0,
    943             /**/                               0, ASSOC_TIMEOUT,        0, 0},    /**/
    944         {StaEvent.TYPE_AUTHENTICATION_FAILURE_EVENT,    -1,            -1,         0,
    945             /**/StaEvent.AUTH_FAILURE_WRONG_PSWD,             0,        0, 0},    /**/
    946         {StaEvent.TYPE_NETWORK_CONNECTION_EVENT,        -1,            -1,         0,
    947             /**/                               0,             0,        0, 0},    /**/
    948         {StaEvent.TYPE_NETWORK_DISCONNECTION_EVENT, DEAUTH_REASON,     -1, LOCAL_GEN,
    949             /**/                               0,             0,        0, 0},    /**/
    950         {StaEvent.TYPE_CMD_ASSOCIATED_BSSID,            -1,            -1,         0,
    951             /**/                               0,             0,  mSupBm1, 0},    /**/
    952         {StaEvent.TYPE_CMD_TARGET_BSSID,                -1,            -1,         0,
    953             /**/                               0,             0,        0, 0},    /**/
    954         {StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL, -1,            -1,         0,
    955             /**/                               0,             0,  mSupBm2, 0},    /**/
    956         {StaEvent.TYPE_CMD_IP_CONFIGURATION_LOST,       -1,            -1,         0,
    957             /**/                               0,             0,        0, 0},    /**/
    958         {StaEvent.TYPE_CMD_IP_REACHABILITY_LOST,        -1,            -1,         0,
    959             /**/                               0,             0,        0, 0},    /**/
    960         {StaEvent.TYPE_CMD_START_CONNECT,               -1,            -1,         0,
    961             /**/                               0,             0,        0, 1},    /**/
    962         {StaEvent.TYPE_CMD_START_ROAM,                  -1,            -1,         0,
    963             /**/                               0,             0,        0, 1},    /**/
    964         {StaEvent.TYPE_CONNECT_NETWORK,                 -1,            -1,         0,
    965             /**/                               0,             0,        0, 1},    /**/
    966         {StaEvent.TYPE_NETWORK_AGENT_VALID_NETWORK,     -1,            -1,         0,
    967             /**/                               0,             0,        0, 0},    /**/
    968         {StaEvent.TYPE_FRAMEWORK_DISCONNECT,            -1,            -1,         0,
    969             /**/                               0,             0,        0, 0}     /**/
    970     };
    971 
    972     /**
    973      * Generates events from all the rows in mTestStaMessageInts, and then mTestStaLogInts
    974      */
    975     private void generateStaEvents(WifiMetrics wifiMetrics) {
    976         Handler handler = wifiMetrics.getHandler();
    977         for (int i = 0; i < mTestStaMessageInts.length; i++) {
    978             int[] mia = mTestStaMessageInts[i];
    979             handler.sendMessage(
    980                     handler.obtainMessage(mia[0], mia[1], mia[2], mTestStaMessageObjs[i]));
    981         }
    982         mTestLooper.dispatchAll();
    983         for (int i = 0; i < mTestStaLogInts.length; i++) {
    984             int[] lia = mTestStaLogInts[i];
    985             wifiMetrics.logStaEvent(lia[0], lia[1], lia[2] == 1 ? mTestWifiConfig : null);
    986         }
    987     }
    988     private void verifyDeserializedStaEvents(WifiMetricsProto.WifiLog wifiLog) {
    989         assertEquals(NUM_TEST_STA_EVENTS, wifiLog.staEventList.length);
    990         int j = 0; // De-serialized event index
    991         for (int i = 0; i < mTestStaMessageInts.length; i++) {
    992             StaEvent event = wifiLog.staEventList[j];
    993             int[] mia = mTestStaMessageInts[i];
    994             int[] evs = mExpectedValues[j];
    995             if (mia[0] != WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT) {
    996                 assertEquals(evs[0], event.type);
    997                 assertEquals(evs[1], event.reason);
    998                 assertEquals(evs[2], event.status);
    999                 assertEquals(evs[3] == 1 ? true : false, event.localGen);
   1000                 assertEquals(evs[4], event.authFailureReason);
   1001                 assertEquals(evs[5] == 1 ? true : false, event.associationTimedOut);
   1002                 assertEquals(evs[6], event.supplicantStateChangesBitmask);
   1003                 assertConfigInfoEqualsWifiConfig(
   1004                         evs[7] == 1 ? mTestWifiConfig : null, event.configInfo);
   1005                 j++;
   1006             }
   1007         }
   1008     }
   1009 
   1010     /**
   1011      * Generate StaEvents of each type, ensure all the different values are logged correctly,
   1012      * and that they survive serialization & de-serialization
   1013      */
   1014     @Test
   1015     public void testStaEventsLogSerializeDeserialize() throws Exception {
   1016         generateStaEvents(mWifiMetrics);
   1017         dumpProtoAndDeserialize();
   1018         verifyDeserializedStaEvents(mDeserializedWifiMetrics);
   1019     }
   1020 
   1021     /**
   1022      * Ensure the number of StaEvents does not exceed MAX_STA_EVENTS by generating lots of events
   1023      * and checking how many are deserialized
   1024      */
   1025     @Test
   1026     public void testStaEventBounding() throws Exception {
   1027         for (int i = 0; i < (WifiMetrics.MAX_STA_EVENTS + 10); i++) {
   1028             mWifiMetrics.logStaEvent(StaEvent.TYPE_CMD_START_CONNECT);
   1029         }
   1030         dumpProtoAndDeserialize();
   1031         assertEquals(WifiMetrics.MAX_STA_EVENTS, mDeserializedWifiMetrics.staEventList.length);
   1032     }
   1033 
   1034     /**
   1035      * Ensure WifiMetrics doesn't cause a null pointer exception when called with null args
   1036      */
   1037     @Test
   1038     public void testDumpNullArg() {
   1039         mWifiMetrics.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null);
   1040     }
   1041 
   1042     /**
   1043      * Generate an RSSI delta event by creating a connection event and an RSSI poll within
   1044      * 'interArrivalTime' milliseconds of each other.
   1045      * Event will not be logged if interArrivalTime > mWifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS
   1046      * successfulConnectionEvent, completeConnectionEvent, useValidScanResult and
   1047      * dontDeserializeBeforePoll
   1048      * each create an anomalous condition when set to false.
   1049      */
   1050     private void generateRssiDelta(int scanRssi, int rssiDelta,
   1051             long interArrivalTime, boolean successfulConnectionEvent,
   1052             boolean completeConnectionEvent, boolean useValidScanResult,
   1053             boolean dontDeserializeBeforePoll) throws Exception {
   1054         when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 0);
   1055         ScanResult scanResult = null;
   1056         if (useValidScanResult) {
   1057             scanResult = mock(ScanResult.class);
   1058             scanResult.level = scanRssi;
   1059         }
   1060         WifiConfiguration config = mock(WifiConfiguration.class);
   1061         WifiConfiguration.NetworkSelectionStatus networkSelectionStat =
   1062                 mock(WifiConfiguration.NetworkSelectionStatus.class);
   1063         when(networkSelectionStat.getCandidate()).thenReturn(scanResult);
   1064         when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStat);
   1065         mWifiMetrics.startConnectionEvent(config, "TestNetwork",
   1066                 WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
   1067         if (completeConnectionEvent) {
   1068             if (successfulConnectionEvent) {
   1069                 mWifiMetrics.endConnectionEvent(
   1070                         WifiMetrics.ConnectionEvent.FAILURE_NONE,
   1071                         WifiMetricsProto.ConnectionEvent.HLF_NONE);
   1072             } else {
   1073                 mWifiMetrics.endConnectionEvent(
   1074                         WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
   1075                         WifiMetricsProto.ConnectionEvent.HLF_NONE);
   1076             }
   1077         }
   1078         when(mClock.getElapsedSinceBootMillis()).thenReturn(interArrivalTime);
   1079         if (!dontDeserializeBeforePoll) {
   1080             dumpProtoAndDeserialize();
   1081         }
   1082         mWifiMetrics.incrementRssiPollRssiCount(scanRssi + rssiDelta);
   1083     }
   1084     /**
   1085      * Generate an RSSI delta event, with all extra conditions set to true.
   1086      */
   1087     private void generateRssiDelta(int scanRssi, int rssiDelta,
   1088             long interArrivalTime) throws Exception {
   1089         generateRssiDelta(scanRssi, rssiDelta, interArrivalTime, true, true, true, true);
   1090     }
   1091 
   1092     private void assertStringContains(
   1093             String actualString, String expectedSubstring) {
   1094         assertTrue("Expected text not found in: " + actualString,
   1095                 actualString.contains(expectedSubstring));
   1096     }
   1097 
   1098     private String getStateDump() {
   1099         ByteArrayOutputStream stream = new ByteArrayOutputStream();
   1100         PrintWriter writer = new PrintWriter(stream);
   1101         String[] args = new String[0];
   1102         mWifiMetrics.dump(null, writer, args);
   1103         writer.flush();
   1104         return stream.toString();
   1105     }
   1106 
   1107     private static final int TEST_ALLOWED_KEY_MANAGEMENT = 83;
   1108     private static final int TEST_ALLOWED_PROTOCOLS = 22;
   1109     private static final int TEST_ALLOWED_AUTH_ALGORITHMS = 11;
   1110     private static final int TEST_ALLOWED_PAIRWISE_CIPHERS = 67;
   1111     private static final int TEST_ALLOWED_GROUP_CIPHERS = 231;
   1112     private static final int TEST_CANDIDATE_LEVEL = -80;
   1113     private static final int TEST_CANDIDATE_FREQ = 2345;
   1114 
   1115     private WifiConfiguration createComplexWifiConfig() {
   1116         WifiConfiguration config = new WifiConfiguration();
   1117         config.allowedKeyManagement = intToBitSet(TEST_ALLOWED_KEY_MANAGEMENT);
   1118         config.allowedProtocols = intToBitSet(TEST_ALLOWED_PROTOCOLS);
   1119         config.allowedAuthAlgorithms = intToBitSet(TEST_ALLOWED_AUTH_ALGORITHMS);
   1120         config.allowedPairwiseCiphers = intToBitSet(TEST_ALLOWED_PAIRWISE_CIPHERS);
   1121         config.allowedGroupCiphers = intToBitSet(TEST_ALLOWED_GROUP_CIPHERS);
   1122         config.hiddenSSID = true;
   1123         config.ephemeral = true;
   1124         config.getNetworkSelectionStatus().setHasEverConnected(true);
   1125         ScanResult candidate = new ScanResult();
   1126         candidate.level = TEST_CANDIDATE_LEVEL;
   1127         candidate.frequency = TEST_CANDIDATE_FREQ;
   1128         config.getNetworkSelectionStatus().setCandidate(candidate);
   1129         return config;
   1130     }
   1131 
   1132     private void assertConfigInfoEqualsWifiConfig(WifiConfiguration config,
   1133             StaEvent.ConfigInfo info) {
   1134         if (config == null && info == null) return;
   1135         assertEquals(config.allowedKeyManagement,   intToBitSet(info.allowedKeyManagement));
   1136         assertEquals(config.allowedProtocols,       intToBitSet(info.allowedProtocols));
   1137         assertEquals(config.allowedAuthAlgorithms,  intToBitSet(info.allowedAuthAlgorithms));
   1138         assertEquals(config.allowedPairwiseCiphers, intToBitSet(info.allowedPairwiseCiphers));
   1139         assertEquals(config.allowedGroupCiphers,    intToBitSet(info.allowedGroupCiphers));
   1140         assertEquals(config.hiddenSSID, info.hiddenSsid);
   1141         assertEquals(config.ephemeral, info.isEphemeral);
   1142         assertEquals(config.getNetworkSelectionStatus().getHasEverConnected(),
   1143                 info.hasEverConnected);
   1144         assertEquals(config.getNetworkSelectionStatus().getCandidate().level, info.scanRssi);
   1145         assertEquals(config.getNetworkSelectionStatus().getCandidate().frequency, info.scanFreq);
   1146     }
   1147 
   1148     /**
   1149      * Sets the values of bitSet to match an int mask
   1150      */
   1151     private static BitSet intToBitSet(int mask) {
   1152         BitSet bitSet = new BitSet();
   1153         for (int bitIndex = 0; mask > 0; mask >>>= 1, bitIndex++) {
   1154             if ((mask & 1) != 0) bitSet.set(bitIndex);
   1155         }
   1156         return bitSet;
   1157     }
   1158 }
   1159