/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */
package com.android.server.wifi;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.*;

import android.net.NetworkAgent;
import android.net.wifi.ScanResult;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiSsid;
import android.os.Handler;
import android.os.test.TestLooper;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Base64;
import android.util.Pair;

import com.android.server.wifi.aware.WifiAwareMetrics;
import com.android.server.wifi.hotspot2.NetworkDetail;
import com.android.server.wifi.hotspot2.PasspointManager;
import com.android.server.wifi.hotspot2.PasspointMatch;
import com.android.server.wifi.hotspot2.PasspointProvider;
import com.android.server.wifi.nano.WifiMetricsProto;
import com.android.server.wifi.nano.WifiMetricsProto.StaEvent;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Unit tests for {@link com.android.server.wifi.WifiMetrics}.
 */
@SmallTest
public class WifiMetricsTest {

    WifiMetrics mWifiMetrics;
    WifiMetricsProto.WifiLog mDecodedProto;
    TestLooper mTestLooper;
    @Mock Clock mClock;
    @Mock WifiConfigManager mWcm;
    @Mock PasspointManager mPpm;
    @Mock WifiNetworkSelector mWns;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mDecodedProto = null;
        when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 0);
        mTestLooper = new TestLooper();
        mWifiMetrics = new WifiMetrics(mClock, mTestLooper.getLooper(),
                new WifiAwareMetrics(mClock));
        mWifiMetrics.setWifiConfigManager(mWcm);
        mWifiMetrics.setPasspointManager(mPpm);
        mWifiMetrics.setWifiNetworkSelector(mWns);
    }

    /**
     * Test that startConnectionEvent and endConnectionEvent can be called repeatedly and out of
     * order. Only tests no exception occurs. Creates 3 ConnectionEvents.
     */
    @Test
    public void startAndEndConnectionEventSucceeds() throws Exception {
        //Start and end Connection event
        mWifiMetrics.startConnectionEvent(null, "RED",
                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
        mWifiMetrics.endConnectionEvent(
                WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
                WifiMetricsProto.ConnectionEvent.HLF_DHCP);
        //end Connection event without starting one
        mWifiMetrics.endConnectionEvent(
                WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
                WifiMetricsProto.ConnectionEvent.HLF_DHCP);
        //start two ConnectionEvents in a row
        mWifiMetrics.startConnectionEvent(null, "BLUE",
                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
        mWifiMetrics.startConnectionEvent(null, "GREEN",
                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
    }

    private static final long TEST_RECORD_DURATION_SEC = 12 * 60 * 60;
    private static final long TEST_RECORD_DURATION_MILLIS = TEST_RECORD_DURATION_SEC * 1000;
    /**
     * Simulate how dumpsys gets the proto from mWifiMetrics, filter the proto bytes out and
     * deserialize them into mDecodedProto
     */
    public void dumpProtoAndDeserialize() throws Exception {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        PrintWriter writer = new PrintWriter(stream);
        String[] args = new String[0];

        when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_RECORD_DURATION_MILLIS);
        //Test proto dump, by passing in proto arg option
        args = new String[]{WifiMetrics.PROTO_DUMP_ARG};
        mWifiMetrics.dump(null, writer, args);
        writer.flush();
        Pattern pattern = Pattern.compile(
                "(?<=WifiMetrics:\\n)([\\s\\S]*)(?=EndWifiMetrics)");
        Matcher matcher = pattern.matcher(stream.toString());
        assertTrue("Proto Byte string found in WifiMetrics.dump():\n" + stream.toString(),
                matcher.find());
        String protoByteString = matcher.group(1);
        byte[] protoBytes = Base64.decode(protoByteString, Base64.DEFAULT);
        mDecodedProto = WifiMetricsProto.WifiLog.parseFrom(protoBytes);
    }

    /**
     * Gets the 'clean dump' proto bytes from mWifiMetrics & deserializes it into
     * mDecodedProto
     */
    public void cleanDumpProtoAndDeserialize() throws Exception {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        PrintWriter writer = new PrintWriter(stream);
        String[] args = new String[0];

        when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_RECORD_DURATION_MILLIS);
        //Test proto dump, by passing in proto arg option
        args = new String[]{WifiMetrics.PROTO_DUMP_ARG, WifiMetrics.CLEAN_DUMP_ARG};
        mWifiMetrics.dump(null, writer, args);
        writer.flush();
        String protoByteString = stream.toString();
        byte[] protoBytes = Base64.decode(protoByteString, Base64.DEFAULT);
        mDecodedProto = WifiMetricsProto.WifiLog.parseFrom(protoBytes);
    }

    /** Verifies that dump() includes the expected header */
    @Test
    public void stateDumpIncludesHeader() throws Exception {
        assertStringContains(getStateDump(), "WifiMetrics");
    }

    /** Verifies that dump() includes correct alert count when there are no alerts. */
    @Test
    public void stateDumpAlertCountIsCorrectWithNoAlerts() throws Exception {
        assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=()");
    }

    /** Verifies that dump() includes correct alert count when there is one alert. */
    @Test
    public void stateDumpAlertCountIsCorrectWithOneAlert() throws Exception {
        mWifiMetrics.incrementAlertReasonCount(1);
        assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=(1,1)");
    }

    /** Verifies that dump() includes correct alert count when there are multiple alerts. */
    @Test
    public void stateDumpAlertCountIsCorrectWithMultipleAlerts() throws Exception {
        mWifiMetrics.incrementAlertReasonCount(1);
        mWifiMetrics.incrementAlertReasonCount(1);
        mWifiMetrics.incrementAlertReasonCount(16);
        assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=(1,2),(16,1)");
    }

    @Test
    public void testDumpProtoAndDeserialize() throws Exception {
        setAndIncrementMetrics();
        dumpProtoAndDeserialize();
        assertDeserializedMetricsCorrect();
    }

    private static final int NUM_OPEN_NETWORKS = 2;
    private static final int NUM_PERSONAL_NETWORKS = 3;
    private static final int NUM_ENTERPRISE_NETWORKS = 5;
    private static final int NUM_SAVED_NETWORKS = NUM_OPEN_NETWORKS + NUM_PERSONAL_NETWORKS
            + NUM_ENTERPRISE_NETWORKS;
    private static final int NUM_HIDDEN_NETWORKS = NUM_OPEN_NETWORKS;
    private static final int NUM_PASSPOINT_NETWORKS = NUM_ENTERPRISE_NETWORKS;
    private static final int NUM_NETWORKS_ADDED_BY_USER = 1;
    private static final int NUM_NETWORKS_ADDED_BY_APPS = NUM_SAVED_NETWORKS
            - NUM_NETWORKS_ADDED_BY_USER;
    private static final boolean TEST_VAL_IS_LOCATION_ENABLED = true;
    private static final boolean IS_SCANNING_ALWAYS_ENABLED = true;
    private static final int NUM_EMPTY_SCAN_RESULTS = 19;
    private static final int NUM_NON_EMPTY_SCAN_RESULTS = 23;
    private static final int NUM_SCAN_UNKNOWN = 1;
    private static final int NUM_SCAN_SUCCESS = 2;
    private static final int NUM_SCAN_FAILURE_INTERRUPTED = 3;
    private static final int NUM_SCAN_FAILURE_INVALID_CONFIGURATION = 5;
    private static final int NUM_WIFI_UNKNOWN_SCREEN_OFF = 3;
    private static final int NUM_WIFI_UNKNOWN_SCREEN_ON = 5;
    private static final int NUM_WIFI_ASSOCIATED_SCREEN_OFF = 7;
    private static final int NUM_WIFI_ASSOCIATED_SCREEN_ON = 11;
    private static final int NUM_CONNECTIVITY_WATCHDOG_PNO_GOOD = 11;
    private static final int NUM_CONNECTIVITY_WATCHDOG_PNO_BAD = 12;
    private static final int NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_GOOD = 13;
    private static final int NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_BAD = 14;
    private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS = 1;
    private static final int NUM_LAST_RESORT_WATCHDOG_BAD_ASSOCIATION_NETWORKS_TOTAL = 2;
    private static final int NUM_LAST_RESORT_WATCHDOG_BAD_AUTHENTICATION_NETWORKS_TOTAL = 3;
    private static final int NUM_LAST_RESORT_WATCHDOG_BAD_DHCP_NETWORKS_TOTAL = 4;
    private static final int NUM_LAST_RESORT_WATCHDOG_BAD_OTHER_NETWORKS_TOTAL = 5;
    private static final int NUM_LAST_RESORT_WATCHDOG_AVAILABLE_NETWORKS_TOTAL = 6;
    private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_ASSOCIATION = 7;
    private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_AUTHENTICATION = 8;
    private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_DHCP = 9;
    private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_OTHER = 10;
    private static final int NUM_LAST_RESORT_WATCHDOG_SUCCESSES = 5;
    private static final int NUM_RSSI_LEVELS_TO_INCREMENT = 20;
    private static final int FIRST_RSSI_LEVEL = -80;
    private static final int NUM_OPEN_NETWORK_SCAN_RESULTS = 1;
    private static final int NUM_PERSONAL_NETWORK_SCAN_RESULTS = 4;
    private static final int NUM_ENTERPRISE_NETWORK_SCAN_RESULTS = 3;
    private static final int NUM_HIDDEN_NETWORK_SCAN_RESULTS = 1;
    private static final int NUM_HOTSPOT2_R1_NETWORK_SCAN_RESULTS = 1;
    private static final int NUM_HOTSPOT2_R2_NETWORK_SCAN_RESULTS = 2;
    private static final int NUM_SCANS = 5;
    private static final int NUM_TOTAL_SCAN_RESULTS = 8;
    private static final int MIN_RSSI_LEVEL = -127;
    private static final int MAX_RSSI_LEVEL = 0;
    private static final int WIFI_SCORE_RANGE_MIN = 0;
    private static final int NUM_WIFI_SCORES_TO_INCREMENT = 20;
    private static final int WIFI_SCORE_RANGE_MAX = 60;
    private static final int NUM_OUT_OF_BOUND_ENTRIES = 10;
    private static final int MAX_NUM_SOFTAP_RETURN_CODES = 3;
    private static final int NUM_SOFTAP_START_SUCCESS = 3;
    private static final int NUM_SOFTAP_FAILED_GENERAL_ERROR = 2;
    private static final int NUM_SOFTAP_FAILED_NO_CHANNEL = 1;
    private static final int NUM_HAL_CRASHES = 11;
    private static final int NUM_WIFICOND_CRASHES = 12;
    private static final int NUM_WIFI_ON_FAILURE_DUE_TO_HAL = 13;
    private static final int NUM_WIFI_ON_FAILURE_DUE_TO_WIFICOND = 14;
    private static final int NUM_PASSPOINT_PROVIDERS = 4;
    private static final int NUM_PASSPOINT_PROVIDER_INSTALLATION = 5;
    private static final int NUM_PASSPOINT_PROVIDER_INSTALL_SUCCESS = 4;
    private static final int NUM_PASSPOINT_PROVIDER_UNINSTALLATION = 3;
    private static final int NUM_PASSPOINT_PROVIDER_UNINSTALL_SUCCESS = 2;
    private static final int NUM_PASSPOINT_PROVIDERS_SUCCESSFULLY_CONNECTED = 1;
    private static final int NUM_PARTIAL_SCAN_RESULTS = 73;

    private ScanDetail buildMockScanDetail(boolean hidden, NetworkDetail.HSRelease hSRelease,
            String capabilities) {
        ScanDetail mockScanDetail = mock(ScanDetail.class);
        NetworkDetail mockNetworkDetail = mock(NetworkDetail.class);
        ScanResult mockScanResult = mock(ScanResult.class);
        when(mockScanDetail.getNetworkDetail()).thenReturn(mockNetworkDetail);
        when(mockScanDetail.getScanResult()).thenReturn(mockScanResult);
        when(mockNetworkDetail.isHiddenBeaconFrame()).thenReturn(hidden);
        when(mockNetworkDetail.getHSRelease()).thenReturn(hSRelease);
        mockScanResult.capabilities = capabilities;
        return mockScanDetail;
    }

    private ScanDetail buildMockScanDetail(String ssid, String bssid, boolean isOpen,
            boolean isSaved, boolean isProvider, boolean isWeakRssi) {
        ScanDetail mockScanDetail = mock(ScanDetail.class);
        NetworkDetail mockNetworkDetail = mock(NetworkDetail.class);
        ScanResult scanResult = new ScanResult();
        scanResult.SSID = ssid;
        scanResult.BSSID = bssid;
        when(mockScanDetail.getNetworkDetail()).thenReturn(mockNetworkDetail);
        when(mockScanDetail.getScanResult()).thenReturn(scanResult);
        when(mWns.isSignalTooWeak(eq(scanResult))).thenReturn(isWeakRssi);
        scanResult.capabilities = isOpen ? "" : "PSK";
        if (isSaved) {
            when(mWcm.getConfiguredNetworkForScanDetail(eq(mockScanDetail)))
                    .thenReturn(mock(WifiConfiguration.class));
        }
        if (isProvider) {
            PasspointProvider provider = mock(PasspointProvider.class);
            Pair<PasspointProvider, PasspointMatch> providerMatch = Pair.create(provider, null);
            when(mockNetworkDetail.isInterworking()).thenReturn(true);
            when(mPpm.matchProvider(eq(scanResult))).thenReturn(providerMatch);
        }
        return mockScanDetail;
    }

    private List<ScanDetail> buildMockScanDetailList() {
        List<ScanDetail> mockScanDetails = new ArrayList<ScanDetail>();
        mockScanDetails.add(buildMockScanDetail(true, null, "[ESS]"));
        mockScanDetails.add(buildMockScanDetail(false, null, "[WPA2-PSK-CCMP][ESS]"));
        mockScanDetails.add(buildMockScanDetail(false, null, "[WPA-PSK-CCMP]"));
        mockScanDetails.add(buildMockScanDetail(false, null, "[WPA-PSK-CCMP]"));
        mockScanDetails.add(buildMockScanDetail(false, null, "[WEP]"));
        mockScanDetails.add(buildMockScanDetail(false, NetworkDetail.HSRelease.R2,
                "[WPA-EAP-CCMP]"));
        mockScanDetails.add(buildMockScanDetail(false, NetworkDetail.HSRelease.R2,
                "[WPA2-EAP+FT/EAP-CCMP]"));
        mockScanDetails.add(buildMockScanDetail(false, NetworkDetail.HSRelease.R1,
                "[WPA-EAP-CCMP]"));
        return mockScanDetails;
    }

    private List<WifiConfiguration> buildSavedNetworkList() {
        List<WifiConfiguration> testSavedNetworks = new ArrayList<WifiConfiguration>();
        for (int i = 0; i < NUM_OPEN_NETWORKS; i++) {
            testSavedNetworks.add(WifiConfigurationTestUtil.createOpenHiddenNetwork());
        }
        for (int i = 0; i < NUM_PERSONAL_NETWORKS; i++) {
            testSavedNetworks.add(WifiConfigurationTestUtil.createPskNetwork());
        }
        for (int i = 0; i < NUM_ENTERPRISE_NETWORKS; i++) {
            // Passpoint networks are counted in both Passpoint and Enterprise counters
            testSavedNetworks.add(WifiConfigurationTestUtil.createPasspointNetwork());
        }
        testSavedNetworks.get(0).selfAdded = true;
        return testSavedNetworks;
    }

    /**
     * Set simple metrics, increment others
     */
    public void setAndIncrementMetrics() throws Exception {
        mWifiMetrics.updateSavedNetworks(buildSavedNetworkList());
        mWifiMetrics.updateSavedPasspointProfiles(NUM_PASSPOINT_PROVIDERS,
                NUM_PASSPOINT_PROVIDERS_SUCCESSFULLY_CONNECTED);
        mWifiMetrics.setIsLocationEnabled(TEST_VAL_IS_LOCATION_ENABLED);
        mWifiMetrics.setIsScanningAlwaysEnabled(IS_SCANNING_ALWAYS_ENABLED);

        for (int i = 0; i < NUM_EMPTY_SCAN_RESULTS; i++) {
            mWifiMetrics.incrementEmptyScanResultCount();
        }
        for (int i = 0; i < NUM_NON_EMPTY_SCAN_RESULTS; i++) {
            mWifiMetrics.incrementNonEmptyScanResultCount();
        }
        mWifiMetrics.incrementScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_UNKNOWN,
                NUM_SCAN_UNKNOWN);
        mWifiMetrics.incrementScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS,
                NUM_SCAN_SUCCESS);
        mWifiMetrics.incrementScanReturnEntry(
                WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED,
                NUM_SCAN_FAILURE_INTERRUPTED);
        mWifiMetrics.incrementScanReturnEntry(
                WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION,
                NUM_SCAN_FAILURE_INVALID_CONFIGURATION);
        for (int i = 0; i < NUM_WIFI_UNKNOWN_SCREEN_OFF; i++) {
            mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN,
                    false);
        }
        for (int i = 0; i < NUM_WIFI_UNKNOWN_SCREEN_ON; i++) {
            mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN,
                    true);
        }
        for (int i = 0; i < NUM_WIFI_ASSOCIATED_SCREEN_OFF; i++) {
            mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED,
                    false);
        }
        for (int i = 0; i < NUM_WIFI_ASSOCIATED_SCREEN_ON; i++) {
            mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED,
                    true);
        }
        for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_PNO_GOOD; i++) {
            mWifiMetrics.incrementNumConnectivityWatchdogPnoGood();
        }
        for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_PNO_BAD; i++) {
            mWifiMetrics.incrementNumConnectivityWatchdogPnoBad();
        }
        for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_GOOD; i++) {
            mWifiMetrics.incrementNumConnectivityWatchdogBackgroundGood();
        }
        for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_BAD; i++) {
            mWifiMetrics.incrementNumConnectivityWatchdogBackgroundBad();
        }
        for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS; i++) {
            mWifiMetrics.incrementNumLastResortWatchdogTriggers();
        }
        mWifiMetrics.addCountToNumLastResortWatchdogBadAssociationNetworksTotal(
                NUM_LAST_RESORT_WATCHDOG_BAD_ASSOCIATION_NETWORKS_TOTAL);
        mWifiMetrics.addCountToNumLastResortWatchdogBadAuthenticationNetworksTotal(
                NUM_LAST_RESORT_WATCHDOG_BAD_AUTHENTICATION_NETWORKS_TOTAL);
        mWifiMetrics.addCountToNumLastResortWatchdogBadDhcpNetworksTotal(
                NUM_LAST_RESORT_WATCHDOG_BAD_DHCP_NETWORKS_TOTAL);
        mWifiMetrics.addCountToNumLastResortWatchdogBadOtherNetworksTotal(
                NUM_LAST_RESORT_WATCHDOG_BAD_OTHER_NETWORKS_TOTAL);
        mWifiMetrics.addCountToNumLastResortWatchdogAvailableNetworksTotal(
                NUM_LAST_RESORT_WATCHDOG_AVAILABLE_NETWORKS_TOTAL);
        for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_ASSOCIATION; i++) {
            mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadAssociation();
        }
        for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_AUTHENTICATION; i++) {
            mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadAuthentication();
        }
        for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_DHCP; i++) {
            mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadDhcp();
        }
        for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_OTHER; i++) {
            mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadOther();
        }
        for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_SUCCESSES; i++) {
            mWifiMetrics.incrementNumLastResortWatchdogSuccesses();
        }
        for (int i = 0; i < NUM_RSSI_LEVELS_TO_INCREMENT; i++) {
            for (int j = 0; j <= i; j++) {
                mWifiMetrics.incrementRssiPollRssiCount(MIN_RSSI_LEVEL + i);
            }
        }
        for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
            mWifiMetrics.incrementRssiPollRssiCount(MIN_RSSI_LEVEL - i);
        }
        for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
            mWifiMetrics.incrementRssiPollRssiCount(MAX_RSSI_LEVEL + i);
        }
        // Test alert-reason clamping.
        mWifiMetrics.incrementAlertReasonCount(WifiLoggerHal.WIFI_ALERT_REASON_MIN - 1);
        mWifiMetrics.incrementAlertReasonCount(WifiLoggerHal.WIFI_ALERT_REASON_MAX + 1);
        // Simple cases for alert reason.
        mWifiMetrics.incrementAlertReasonCount(1);
        mWifiMetrics.incrementAlertReasonCount(1);
        mWifiMetrics.incrementAlertReasonCount(1);
        mWifiMetrics.incrementAlertReasonCount(2);
        List<ScanDetail> mockScanDetails = buildMockScanDetailList();
        for (int i = 0; i < NUM_SCANS; i++) {
            mWifiMetrics.countScanResults(mockScanDetails);
        }
        for (int score = WIFI_SCORE_RANGE_MIN; score < NUM_WIFI_SCORES_TO_INCREMENT; score++) {
            for (int offset = 0; offset <= score; offset++) {
                mWifiMetrics.incrementWifiScoreCount(WIFI_SCORE_RANGE_MIN + score);
            }
        }
        for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
            mWifiMetrics.incrementWifiScoreCount(WIFI_SCORE_RANGE_MIN - i);
        }
        for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
            mWifiMetrics.incrementWifiScoreCount(WIFI_SCORE_RANGE_MAX + i);
        }

        // increment soft ap start return codes
        for (int i = 0; i < NUM_SOFTAP_START_SUCCESS; i++) {
            mWifiMetrics.incrementSoftApStartResult(true, 0);
        }
        for (int i = 0; i < NUM_SOFTAP_FAILED_GENERAL_ERROR; i++) {
            mWifiMetrics.incrementSoftApStartResult(false, WifiManager.SAP_START_FAILURE_GENERAL);
        }
        for (int i = 0; i < NUM_SOFTAP_FAILED_NO_CHANNEL; i++) {
            mWifiMetrics.incrementSoftApStartResult(false,
                    WifiManager.SAP_START_FAILURE_NO_CHANNEL);
        }
        for (int i = 0; i < NUM_HAL_CRASHES; i++) {
            mWifiMetrics.incrementNumHalCrashes();
        }
        for (int i = 0; i < NUM_WIFICOND_CRASHES; i++) {
            mWifiMetrics.incrementNumWificondCrashes();
        }
        for (int i = 0; i < NUM_WIFI_ON_FAILURE_DUE_TO_HAL; i++) {
            mWifiMetrics.incrementNumWifiOnFailureDueToHal();
        }
        for (int i = 0; i < NUM_WIFI_ON_FAILURE_DUE_TO_WIFICOND; i++) {
            mWifiMetrics.incrementNumWifiOnFailureDueToWificond();
        }
        for (int i = 0; i < NUM_PASSPOINT_PROVIDER_INSTALLATION; i++) {
            mWifiMetrics.incrementNumPasspointProviderInstallation();
        }
        for (int i = 0; i < NUM_PASSPOINT_PROVIDER_INSTALL_SUCCESS; i++) {
            mWifiMetrics.incrementNumPasspointProviderInstallSuccess();
        }
        for (int i = 0; i < NUM_PASSPOINT_PROVIDER_UNINSTALLATION; i++) {
            mWifiMetrics.incrementNumPasspointProviderUninstallation();
        }
        for (int i = 0; i < NUM_PASSPOINT_PROVIDER_UNINSTALL_SUCCESS; i++) {
            mWifiMetrics.incrementNumPasspointProviderUninstallSuccess();
        }
    }

    /**
     * Assert that values in deserializedWifiMetrics match those set in 'setAndIncrementMetrics'
     */
    public void assertDeserializedMetricsCorrect() throws Exception {
        assertEquals("mDecodedProto.numSavedNetworks == NUM_SAVED_NETWORKS",
                mDecodedProto.numSavedNetworks, NUM_SAVED_NETWORKS);
        assertEquals("mDecodedProto.numOpenNetworks == NUM_OPEN_NETWORKS",
                mDecodedProto.numOpenNetworks, NUM_OPEN_NETWORKS);
        assertEquals("mDecodedProto.numPersonalNetworks == NUM_PERSONAL_NETWORKS",
                mDecodedProto.numPersonalNetworks, NUM_PERSONAL_NETWORKS);
        assertEquals("mDecodedProto.numEnterpriseNetworks == NUM_ENTERPRISE_NETWORKS",
                mDecodedProto.numEnterpriseNetworks, NUM_ENTERPRISE_NETWORKS);
        assertEquals("mDecodedProto.numNetworksAddedByUser == NUM_NETWORKS_ADDED_BY_USER",
                mDecodedProto.numNetworksAddedByUser, NUM_NETWORKS_ADDED_BY_USER);
        assertEquals(NUM_HIDDEN_NETWORKS, mDecodedProto.numHiddenNetworks);
        assertEquals(NUM_PASSPOINT_NETWORKS, mDecodedProto.numPasspointNetworks);
        assertEquals("mDecodedProto.numNetworksAddedByApps == NUM_NETWORKS_ADDED_BY_APPS",
                mDecodedProto.numNetworksAddedByApps, NUM_NETWORKS_ADDED_BY_APPS);
        assertEquals("mDecodedProto.isLocationEnabled == TEST_VAL_IS_LOCATION_ENABLED",
                mDecodedProto.isLocationEnabled, TEST_VAL_IS_LOCATION_ENABLED);
        assertEquals("mDecodedProto.isScanningAlwaysEnabled == IS_SCANNING_ALWAYS_ENABLED",
                mDecodedProto.isScanningAlwaysEnabled, IS_SCANNING_ALWAYS_ENABLED);
        assertEquals("mDecodedProto.numEmptyScanResults == NUM_EMPTY_SCAN_RESULTS",
                mDecodedProto.numEmptyScanResults, NUM_EMPTY_SCAN_RESULTS);
        assertEquals("mDecodedProto.numNonEmptyScanResults == NUM_NON_EMPTY_SCAN_RESULTS",
                mDecodedProto.numNonEmptyScanResults, NUM_NON_EMPTY_SCAN_RESULTS);
        assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_UNKNOWN, NUM_SCAN_UNKNOWN);
        assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_SUCCESS, NUM_SCAN_SUCCESS);
        assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED,
                NUM_SCAN_FAILURE_INTERRUPTED);
        assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION,
                NUM_SCAN_FAILURE_INVALID_CONFIGURATION);
        assertSystemStateEntryEquals(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, false,
                NUM_WIFI_UNKNOWN_SCREEN_OFF);
        assertSystemStateEntryEquals(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, true,
                NUM_WIFI_UNKNOWN_SCREEN_ON);
        assertSystemStateEntryEquals(
                WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, false, NUM_WIFI_ASSOCIATED_SCREEN_OFF);
        assertSystemStateEntryEquals(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, true,
                NUM_WIFI_ASSOCIATED_SCREEN_ON);
        assertEquals(mDecodedProto.numConnectivityWatchdogPnoGood,
                NUM_CONNECTIVITY_WATCHDOG_PNO_GOOD);
        assertEquals(mDecodedProto.numConnectivityWatchdogPnoBad,
                NUM_CONNECTIVITY_WATCHDOG_PNO_BAD);
        assertEquals(mDecodedProto.numConnectivityWatchdogBackgroundGood,
                NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_GOOD);
        assertEquals(mDecodedProto.numConnectivityWatchdogBackgroundBad,
                NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_BAD);
        assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS,
                mDecodedProto.numLastResortWatchdogTriggers);
        assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_ASSOCIATION_NETWORKS_TOTAL,
                mDecodedProto.numLastResortWatchdogBadAssociationNetworksTotal);
        assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_AUTHENTICATION_NETWORKS_TOTAL,
                mDecodedProto.numLastResortWatchdogBadAuthenticationNetworksTotal);
        assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_DHCP_NETWORKS_TOTAL,
                mDecodedProto.numLastResortWatchdogBadDhcpNetworksTotal);
        assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_OTHER_NETWORKS_TOTAL,
                mDecodedProto.numLastResortWatchdogBadOtherNetworksTotal);
        assertEquals(NUM_LAST_RESORT_WATCHDOG_AVAILABLE_NETWORKS_TOTAL,
                mDecodedProto.numLastResortWatchdogAvailableNetworksTotal);
        assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_ASSOCIATION,
                mDecodedProto.numLastResortWatchdogTriggersWithBadAssociation);
        assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_AUTHENTICATION,
                mDecodedProto.numLastResortWatchdogTriggersWithBadAuthentication);
        assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_DHCP,
                mDecodedProto.numLastResortWatchdogTriggersWithBadDhcp);
        assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_OTHER,
                mDecodedProto.numLastResortWatchdogTriggersWithBadOther);
        assertEquals(NUM_LAST_RESORT_WATCHDOG_SUCCESSES,
                mDecodedProto.numLastResortWatchdogSuccesses);
        assertEquals(TEST_RECORD_DURATION_SEC,
                mDecodedProto.recordDurationSec);
        for (int i = 0; i < NUM_RSSI_LEVELS_TO_INCREMENT; i++) {
            assertEquals(MIN_RSSI_LEVEL + i, mDecodedProto.rssiPollRssiCount[i].rssi);
            assertEquals(i + 1, mDecodedProto.rssiPollRssiCount[i].count);
        }
        StringBuilder sb_rssi = new StringBuilder();
        sb_rssi.append("Number of RSSIs = " + mDecodedProto.rssiPollRssiCount.length);
        assertTrue(sb_rssi.toString(), (mDecodedProto.rssiPollRssiCount.length
                     <= (MAX_RSSI_LEVEL - MIN_RSSI_LEVEL + 1)));
        assertEquals(2, mDecodedProto.alertReasonCount[0].count);  // Clamped reasons.
        assertEquals(3, mDecodedProto.alertReasonCount[1].count);
        assertEquals(1, mDecodedProto.alertReasonCount[2].count);
        assertEquals(3, mDecodedProto.alertReasonCount.length);
        assertEquals(NUM_TOTAL_SCAN_RESULTS * NUM_SCANS,
                mDecodedProto.numTotalScanResults);
        assertEquals(NUM_OPEN_NETWORK_SCAN_RESULTS * NUM_SCANS,
                mDecodedProto.numOpenNetworkScanResults);
        assertEquals(NUM_PERSONAL_NETWORK_SCAN_RESULTS * NUM_SCANS,
                mDecodedProto.numPersonalNetworkScanResults);
        assertEquals(NUM_ENTERPRISE_NETWORK_SCAN_RESULTS * NUM_SCANS,
                mDecodedProto.numEnterpriseNetworkScanResults);
        assertEquals(NUM_HIDDEN_NETWORK_SCAN_RESULTS * NUM_SCANS,
                mDecodedProto.numHiddenNetworkScanResults);
        assertEquals(NUM_HOTSPOT2_R1_NETWORK_SCAN_RESULTS * NUM_SCANS,
                mDecodedProto.numHotspot2R1NetworkScanResults);
        assertEquals(NUM_HOTSPOT2_R2_NETWORK_SCAN_RESULTS * NUM_SCANS,
                mDecodedProto.numHotspot2R2NetworkScanResults);
        assertEquals(NUM_SCANS,
                mDecodedProto.numScans);
        for (int score_index = 0; score_index < NUM_WIFI_SCORES_TO_INCREMENT; score_index++) {
            assertEquals(WIFI_SCORE_RANGE_MIN + score_index,
                    mDecodedProto.wifiScoreCount[score_index].score);
            assertEquals(score_index + 1,
                    mDecodedProto.wifiScoreCount[score_index].count);
        }
        StringBuilder sb_wifi_score = new StringBuilder();
        sb_wifi_score.append("Number of wifi_scores = " + mDecodedProto.wifiScoreCount.length);
        assertTrue(sb_wifi_score.toString(), (mDecodedProto.wifiScoreCount.length
                <= (WIFI_SCORE_RANGE_MAX - WIFI_SCORE_RANGE_MIN + 1)));
        StringBuilder sb_wifi_limits = new StringBuilder();
        sb_wifi_limits.append("Wifi Score limit is " +  NetworkAgent.WIFI_BASE_SCORE
                + ">= " + WIFI_SCORE_RANGE_MAX);
        assertTrue(sb_wifi_limits.toString(), NetworkAgent.WIFI_BASE_SCORE <= WIFI_SCORE_RANGE_MAX);
        assertEquals(MAX_NUM_SOFTAP_RETURN_CODES, mDecodedProto.softApReturnCode.length);
        assertEquals(WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_STARTED_SUCCESSFULLY,
                     mDecodedProto.softApReturnCode[0].startResult);
        assertEquals(NUM_SOFTAP_START_SUCCESS, mDecodedProto.softApReturnCode[0].count);
        assertEquals(WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_GENERAL_ERROR,
                     mDecodedProto.softApReturnCode[1].startResult);
        assertEquals(NUM_SOFTAP_FAILED_GENERAL_ERROR,
                     mDecodedProto.softApReturnCode[1].count);
        assertEquals(WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_NO_CHANNEL,
                     mDecodedProto.softApReturnCode[2].startResult);
        assertEquals(NUM_SOFTAP_FAILED_NO_CHANNEL,
                     mDecodedProto.softApReturnCode[2].count);
        assertEquals(NUM_HAL_CRASHES, mDecodedProto.numHalCrashes);
        assertEquals(NUM_WIFICOND_CRASHES, mDecodedProto.numWificondCrashes);
        assertEquals(NUM_WIFI_ON_FAILURE_DUE_TO_HAL, mDecodedProto.numWifiOnFailureDueToHal);
        assertEquals(NUM_WIFI_ON_FAILURE_DUE_TO_WIFICOND,
                mDecodedProto.numWifiOnFailureDueToWificond);
        assertEquals(NUM_PASSPOINT_PROVIDERS, mDecodedProto.numPasspointProviders);
        assertEquals(NUM_PASSPOINT_PROVIDER_INSTALLATION,
                mDecodedProto.numPasspointProviderInstallation);
        assertEquals(NUM_PASSPOINT_PROVIDER_INSTALL_SUCCESS,
                mDecodedProto.numPasspointProviderInstallSuccess);
        assertEquals(NUM_PASSPOINT_PROVIDER_UNINSTALLATION,
                mDecodedProto.numPasspointProviderUninstallation);
        assertEquals(NUM_PASSPOINT_PROVIDER_UNINSTALL_SUCCESS,
                mDecodedProto.numPasspointProviderUninstallSuccess);
        assertEquals(NUM_PASSPOINT_PROVIDERS_SUCCESSFULLY_CONNECTED,
                mDecodedProto.numPasspointProvidersSuccessfullyConnected);
    }

    /**
     *  Assert deserialized metrics Scan Return Entry equals count
     */
    public void assertScanReturnEntryEquals(int returnCode, int count) {
        for (int i = 0; i < mDecodedProto.scanReturnEntries.length; i++) {
            if (mDecodedProto.scanReturnEntries[i].scanReturnCode == returnCode) {
                assertEquals(mDecodedProto.scanReturnEntries[i].scanResultsCount, count);
                return;
            }
        }
        assertEquals(null, count);
    }

    /**
     *  Assert deserialized metrics SystemState entry equals count
     */
    public void assertSystemStateEntryEquals(int state, boolean screenOn, int count) {
        for (int i = 0; i < mDecodedProto.wifiSystemStateEntries.length; i++) {
            if (mDecodedProto.wifiSystemStateEntries[i].wifiState == state
                    && mDecodedProto.wifiSystemStateEntries[i].isScreenOn == screenOn) {
                assertEquals(mDecodedProto.wifiSystemStateEntries[i].wifiStateCount,
                        count);
                return;
            }
        }
        assertEquals(null, count);
    }
    /**
     * Combination of all other WifiMetrics unit tests, an internal-integration test, or functional
     * test
     */
    @Test
    public void setMetricsSerializeDeserializeAssertMetricsSame() throws Exception {
        setAndIncrementMetrics();
        startAndEndConnectionEventSucceeds();
        dumpProtoAndDeserialize();
        assertDeserializedMetricsCorrect();
        assertEquals("mDecodedProto.connectionEvent.length",
                2, mDecodedProto.connectionEvent.length);
        //<TODO> test individual connectionEvents for correctness,
        // check scanReturnEntries & wifiSystemStateEntries counts and individual elements
        // pending their implementation</TODO>
    }

    private static final String SSID = "red";
    private static final int CONFIG_DTIM = 3;
    private static final int NETWORK_DETAIL_WIFIMODE = 5;
    private static final int NETWORK_DETAIL_DTIM = 7;
    private static final int SCAN_RESULT_LEVEL = -30;
    /**
     * Test that WifiMetrics is correctly getting data from ScanDetail and WifiConfiguration
     */
    @Test
    public void testScanDetailAndWifiConfigurationUsage() 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;
        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);

        //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);

        //Create a connection event using the config and a scan detail
        mWifiMetrics.startConnectionEvent(config, "Green",
                WifiMetricsProto.ConnectionEvent.ROAM_NONE);
        mWifiMetrics.setConnectionScanDetail(scanDetail);
        mWifiMetrics.endConnectionEvent(
                WifiMetrics.ConnectionEvent.FAILURE_NONE,
                WifiMetricsProto.ConnectionEvent.HLF_NONE);

        //Dump proto from mWifiMetrics and deserialize it to mDecodedProto
        dumpProtoAndDeserialize();

        //Check that the correct values are being flowed through
        assertEquals(mDecodedProto.connectionEvent.length, 2);
        assertEquals(mDecodedProto.connectionEvent[0].routerFingerprint.dtim,
                CONFIG_DTIM);
        assertEquals(mDecodedProto.connectionEvent[0].signalStrength, SCAN_RESULT_LEVEL);
        assertEquals(mDecodedProto.connectionEvent[1].routerFingerprint.dtim,
                NETWORK_DETAIL_DTIM);
        assertEquals(mDecodedProto.connectionEvent[1].signalStrength,
                SCAN_RESULT_LEVEL);
        assertEquals(mDecodedProto.connectionEvent[1].routerFingerprint.routerTechnology,
                NETWORK_DETAIL_WIFIMODE);
    }

    /**
     * Test that WifiMetrics is being cleared after dumping via proto
     */
    @Test
    public void testMetricsClearedAfterProtoRequested() throws Exception {
        // Create 3 ConnectionEvents
        mWifiMetrics.startConnectionEvent(null, "RED",
                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
        mWifiMetrics.endConnectionEvent(
                WifiMetrics.ConnectionEvent.FAILURE_NONE,
                WifiMetricsProto.ConnectionEvent.HLF_NONE);
        mWifiMetrics.startConnectionEvent(null, "YELLOW",
                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
        mWifiMetrics.endConnectionEvent(
                WifiMetrics.ConnectionEvent.FAILURE_NONE,
                WifiMetricsProto.ConnectionEvent.HLF_NONE);
        mWifiMetrics.startConnectionEvent(null, "GREEN",
                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
        mWifiMetrics.endConnectionEvent(
                WifiMetrics.ConnectionEvent.FAILURE_NONE,
                WifiMetricsProto.ConnectionEvent.HLF_NONE);
        mWifiMetrics.startConnectionEvent(null, "ORANGE",
                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
        mWifiMetrics.endConnectionEvent(
                WifiMetrics.ConnectionEvent.FAILURE_NONE,
                WifiMetricsProto.ConnectionEvent.HLF_NONE);

        //Dump proto and deserialize
        //This should clear all the metrics in mWifiMetrics,
        dumpProtoAndDeserialize();
        //Check there are only 3 connection events
        assertEquals(mDecodedProto.connectionEvent.length, 4);
        assertEquals(mDecodedProto.rssiPollRssiCount.length, 0);
        assertEquals(mDecodedProto.alertReasonCount.length, 0);

        // Create 2 ConnectionEvents
        mWifiMetrics.startConnectionEvent(null,  "BLUE",
                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
        mWifiMetrics.endConnectionEvent(
                WifiMetrics.ConnectionEvent.FAILURE_NONE,
                WifiMetricsProto.ConnectionEvent.HLF_NONE);
        mWifiMetrics.startConnectionEvent(null, "RED",
                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
        mWifiMetrics.endConnectionEvent(
                WifiMetrics.ConnectionEvent.FAILURE_NONE,
                WifiMetricsProto.ConnectionEvent.HLF_NONE);

        //Dump proto and deserialize
        dumpProtoAndDeserialize();
        //Check there are only 2 connection events
        assertEquals(mDecodedProto.connectionEvent.length, 2);
    }

    /**
     * Tests that after setting metrics values they can be serialized and deserialized with the
     *   $ adb shell dumpsys wifi wifiMetricsProto clean
     */
    @Test
    public void testClearMetricsDump() throws Exception {
        setAndIncrementMetrics();
        startAndEndConnectionEventSucceeds();
        cleanDumpProtoAndDeserialize();
        assertDeserializedMetricsCorrect();
        assertEquals("mDecodedProto.connectionEvent.length",
                2, mDecodedProto.connectionEvent.length);
    }

    private static final int NUM_REPEATED_DELTAS = 7;
    private static final int REPEATED_DELTA = 0;
    private static final int SINGLE_GOOD_DELTA = 1;
    private static final int SINGLE_TIMEOUT_DELTA = 2;
    private static final int NUM_REPEATED_BOUND_DELTAS = 2;
    private static final int MAX_DELTA_LEVEL = 127;
    private static final int MIN_DELTA_LEVEL = -127;
    private static final int ARBITRARY_DELTA_LEVEL = 20;

    /**
     * Sunny day RSSI delta logging scenario.
     * Logs one rssi delta value multiple times
     * Logs a different delta value a single time
     */
    @Test
    public void testRssiDeltasSuccessfulLogging() throws Exception {
        // Generate some repeated deltas
        for (int i = 0; i < NUM_REPEATED_DELTAS; i++) {
            generateRssiDelta(MIN_RSSI_LEVEL, REPEATED_DELTA,
                    WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
        }
        // Generate a single delta
        generateRssiDelta(MIN_RSSI_LEVEL, SINGLE_GOOD_DELTA,
                WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
        dumpProtoAndDeserialize();
        assertEquals(2, mDecodedProto.rssiPollDeltaCount.length);
        // Check the repeated deltas
        assertEquals(NUM_REPEATED_DELTAS, mDecodedProto.rssiPollDeltaCount[0].count);
        assertEquals(REPEATED_DELTA, mDecodedProto.rssiPollDeltaCount[0].rssi);
        // Check the single delta
        assertEquals(1, mDecodedProto.rssiPollDeltaCount[1].count);
        assertEquals(SINGLE_GOOD_DELTA, mDecodedProto.rssiPollDeltaCount[1].rssi);
    }

    /**
     * Tests that Rssi Delta events whose scanResult and Rssi Poll come too far apart, timeout,
     * and are not logged.
     */
    @Test
    public void testRssiDeltasTimeout() throws Exception {
        // Create timed out rssi deltas
        generateRssiDelta(MIN_RSSI_LEVEL, REPEATED_DELTA,
                WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS + 1);
        generateRssiDelta(MIN_RSSI_LEVEL, SINGLE_TIMEOUT_DELTA,
                WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS + 1);
        dumpProtoAndDeserialize();
        assertEquals(0, mDecodedProto.rssiPollDeltaCount.length);
    }

    /**
     * Tests the exact inclusive boundaries of RSSI delta logging.
     */
    @Test
    public void testRssiDeltaSuccessfulLoggingExactBounds() throws Exception {
        generateRssiDelta(MIN_RSSI_LEVEL, MAX_DELTA_LEVEL,
                WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
        generateRssiDelta(MAX_RSSI_LEVEL, MIN_DELTA_LEVEL,
                WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
        dumpProtoAndDeserialize();
        assertEquals(2, mDecodedProto.rssiPollDeltaCount.length);
        assertEquals(MIN_DELTA_LEVEL, mDecodedProto.rssiPollDeltaCount[0].rssi);
        assertEquals(1, mDecodedProto.rssiPollDeltaCount[0].count);
        assertEquals(MAX_DELTA_LEVEL, mDecodedProto.rssiPollDeltaCount[1].rssi);
        assertEquals(1, mDecodedProto.rssiPollDeltaCount[1].count);
    }

    /**
     * Tests the exact exclusive boundaries of RSSI delta logging.
     * This test ensures that too much data is not generated.
     */
    @Test
    public void testRssiDeltaOutOfBounds() throws Exception {
        generateRssiDelta(MIN_RSSI_LEVEL, MAX_DELTA_LEVEL + 1,
                WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
        generateRssiDelta(MAX_RSSI_LEVEL, MIN_DELTA_LEVEL - 1,
                WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
        dumpProtoAndDeserialize();
        assertEquals(0, mDecodedProto.rssiPollDeltaCount.length);
    }

    /**
     * This test ensures no rssi Delta is logged after an unsuccessful ConnectionEvent
     */
    @Test
    public void testUnsuccesfulConnectionEventRssiDeltaIsNotLogged() throws Exception {
        generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL,
                WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS,
                false, // successfulConnectionEvent
                true, // completeConnectionEvent
                true, // useValidScanResult
                true // dontDeserializeBeforePoll
        );

        dumpProtoAndDeserialize();
        assertEquals(0, mDecodedProto.rssiPollDeltaCount.length);
    }

    /**
     * This test ensures rssi Deltas can be logged during a ConnectionEvent
     */
    @Test
    public void testIncompleteConnectionEventRssiDeltaIsLogged() throws Exception {
        generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL,
                WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS,
                true, // successfulConnectionEvent
                false, // completeConnectionEvent
                true, // useValidScanResult
                true // dontDeserializeBeforePoll
        );
        dumpProtoAndDeserialize();
        assertEquals(1, mDecodedProto.rssiPollDeltaCount.length);
        assertEquals(ARBITRARY_DELTA_LEVEL, mDecodedProto.rssiPollDeltaCount[0].rssi);
        assertEquals(1, mDecodedProto.rssiPollDeltaCount[0].count);
    }

    /**
     * This test ensures that no delta is logged for a null ScanResult Candidate
     */
    @Test
    public void testRssiDeltaNotLoggedForNullCandidateScanResult() throws Exception {
        generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL,
                WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS,
                true, // successfulConnectionEvent
                true, // completeConnectionEvent
                false, // useValidScanResult
                true // dontDeserializeBeforePoll
        );
        dumpProtoAndDeserialize();
        assertEquals(0, mDecodedProto.rssiPollDeltaCount.length);
    }

    /**
     * This test ensures that Rssi Deltas are not logged over a 'clear()' call (Metrics Serialized)
     */
    @Test
    public void testMetricsSerializedDuringRssiDeltaEventLogsNothing() throws Exception {
        generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL,
                WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS,
                true, // successfulConnectionEvent
                true, // completeConnectionEvent
                true, // useValidScanResult
                false // dontDeserializeBeforePoll
        );
        dumpProtoAndDeserialize();
        assertEquals(0, mDecodedProto.rssiPollDeltaCount.length);
    }

    private static final int DEAUTH_REASON = 7;
    private static final int ASSOC_STATUS = 11;
    private static final int ASSOC_TIMEOUT = 1;
    private static final int LOCAL_GEN = 1;
    private static final int AUTH_FAILURE_REASON = WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD;
    private static final int NUM_TEST_STA_EVENTS = 14;
    private static final String   sSSID = "\"SomeTestSsid\"";
    private static final WifiSsid sWifiSsid = WifiSsid.createFromAsciiEncoded(sSSID);
    private static final String   sBSSID = "01:02:03:04:05:06";

    private final StateChangeResult mStateDisconnected =
            new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.DISCONNECTED);
    private final StateChangeResult mStateCompleted =
            new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED);
    // Test bitmasks of supplicant state changes
    private final int mSupBm1 = WifiMetrics.supplicantStateToBit(mStateDisconnected.state);
    private final int mSupBm2 = WifiMetrics.supplicantStateToBit(mStateDisconnected.state)
            | WifiMetrics.supplicantStateToBit(mStateCompleted.state);
    // An invalid but interesting wifiConfiguration that exercises the StaEvent.ConfigInfo encoding
    private final WifiConfiguration mTestWifiConfig = createComplexWifiConfig();
    // <msg.what> <msg.arg1> <msg.arg2>
    private int[][] mTestStaMessageInts = {
        {WifiMonitor.ASSOCIATION_REJECTION_EVENT,   ASSOC_TIMEOUT,      ASSOC_STATUS},
        {WifiMonitor.AUTHENTICATION_FAILURE_EVENT,  0,                  AUTH_FAILURE_REASON},
        {WifiMonitor.NETWORK_CONNECTION_EVENT,      0,                  0},
        {WifiMonitor.NETWORK_DISCONNECTION_EVENT,   LOCAL_GEN,          DEAUTH_REASON},
        {WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0,                  0},
        {WifiStateMachine.CMD_ASSOCIATED_BSSID,     0,                  0},
        {WifiStateMachine.CMD_TARGET_BSSID,         0,                  0},
        {WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0,                  0},
        {WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0,                  0}
    };
    private Object[] mTestStaMessageObjs = {
        null,
        null,
        null,
        null,
        mStateDisconnected,
        null,
        null,
        mStateDisconnected,
        mStateCompleted
    };
    // Values used to generate the StaEvent log calls from WifiStateMachine
    // <StaEvent.Type>, <StaEvent.FrameworkDisconnectReason>, <1|0>(testWifiConfiguration, null)
    private int[][] mTestStaLogInts = {
        {StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL, 0,                          0},
        {StaEvent.TYPE_CMD_IP_CONFIGURATION_LOST,       0,                          0},
        {StaEvent.TYPE_CMD_IP_REACHABILITY_LOST,        0,                          0},
        {StaEvent.TYPE_CMD_START_CONNECT,               0,                          1},
        {StaEvent.TYPE_CMD_START_ROAM,                  0,                          1},
        {StaEvent.TYPE_CONNECT_NETWORK,                 0,                          1},
        {StaEvent.TYPE_NETWORK_AGENT_VALID_NETWORK,     0,                          0},
        {StaEvent.TYPE_FRAMEWORK_DISCONNECT,            StaEvent.DISCONNECT_API,    0}
    };
    // Values used to generate the StaEvent log calls from WifiMonitor
    // <type>, <reason>, <status>, <local_gen>,
    // <auth_fail_reason>, <assoc_timed_out> <supplicantStateChangeBitmask> <1|0>(has ConfigInfo)
    private int[][] mExpectedValues = {
        {StaEvent.TYPE_ASSOCIATION_REJECTION_EVENT,     -1,  ASSOC_STATUS,         0,
            /**/                               0, ASSOC_TIMEOUT,        0, 0},    /**/
        {StaEvent.TYPE_AUTHENTICATION_FAILURE_EVENT,    -1,            -1,         0,
            /**/StaEvent.AUTH_FAILURE_WRONG_PSWD,             0,        0, 0},    /**/
        {StaEvent.TYPE_NETWORK_CONNECTION_EVENT,        -1,            -1,         0,
            /**/                               0,             0,        0, 0},    /**/
        {StaEvent.TYPE_NETWORK_DISCONNECTION_EVENT, DEAUTH_REASON,     -1, LOCAL_GEN,
            /**/                               0,             0,        0, 0},    /**/
        {StaEvent.TYPE_CMD_ASSOCIATED_BSSID,            -1,            -1,         0,
            /**/                               0,             0,  mSupBm1, 0},    /**/
        {StaEvent.TYPE_CMD_TARGET_BSSID,                -1,            -1,         0,
            /**/                               0,             0,        0, 0},    /**/
        {StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL, -1,            -1,         0,
            /**/                               0,             0,  mSupBm2, 0},    /**/
        {StaEvent.TYPE_CMD_IP_CONFIGURATION_LOST,       -1,            -1,         0,
            /**/                               0,             0,        0, 0},    /**/
        {StaEvent.TYPE_CMD_IP_REACHABILITY_LOST,        -1,            -1,         0,
            /**/                               0,             0,        0, 0},    /**/
        {StaEvent.TYPE_CMD_START_CONNECT,               -1,            -1,         0,
            /**/                               0,             0,        0, 1},    /**/
        {StaEvent.TYPE_CMD_START_ROAM,                  -1,            -1,         0,
            /**/                               0,             0,        0, 1},    /**/
        {StaEvent.TYPE_CONNECT_NETWORK,                 -1,            -1,         0,
            /**/                               0,             0,        0, 1},    /**/
        {StaEvent.TYPE_NETWORK_AGENT_VALID_NETWORK,     -1,            -1,         0,
            /**/                               0,             0,        0, 0},    /**/
        {StaEvent.TYPE_FRAMEWORK_DISCONNECT,            -1,            -1,         0,
            /**/                               0,             0,        0, 0}     /**/
    };

    /**
     * Generates events from all the rows in mTestStaMessageInts, and then mTestStaLogInts
     */
    private void generateStaEvents(WifiMetrics wifiMetrics) {
        Handler handler = wifiMetrics.getHandler();
        for (int i = 0; i < mTestStaMessageInts.length; i++) {
            int[] mia = mTestStaMessageInts[i];
            handler.sendMessage(
                    handler.obtainMessage(mia[0], mia[1], mia[2], mTestStaMessageObjs[i]));
        }
        mTestLooper.dispatchAll();
        for (int i = 0; i < mTestStaLogInts.length; i++) {
            int[] lia = mTestStaLogInts[i];
            wifiMetrics.logStaEvent(lia[0], lia[1], lia[2] == 1 ? mTestWifiConfig : null);
        }
    }
    private void verifyDeserializedStaEvents(WifiMetricsProto.WifiLog wifiLog) {
        assertEquals(NUM_TEST_STA_EVENTS, wifiLog.staEventList.length);
        int j = 0; // De-serialized event index
        for (int i = 0; i < mTestStaMessageInts.length; i++) {
            StaEvent event = wifiLog.staEventList[j];
            int[] mia = mTestStaMessageInts[i];
            int[] evs = mExpectedValues[j];
            if (mia[0] != WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT) {
                assertEquals(evs[0], event.type);
                assertEquals(evs[1], event.reason);
                assertEquals(evs[2], event.status);
                assertEquals(evs[3] == 1 ? true : false, event.localGen);
                assertEquals(evs[4], event.authFailureReason);
                assertEquals(evs[5] == 1 ? true : false, event.associationTimedOut);
                assertEquals(evs[6], event.supplicantStateChangesBitmask);
                assertConfigInfoEqualsWifiConfig(
                        evs[7] == 1 ? mTestWifiConfig : null, event.configInfo);
                j++;
            }
        }
    }

    /**
     * Generate StaEvents of each type, ensure all the different values are logged correctly,
     * and that they survive serialization & de-serialization
     */
    @Test
    public void testStaEventsLogSerializeDeserialize() throws Exception {
        generateStaEvents(mWifiMetrics);
        dumpProtoAndDeserialize();
        verifyDeserializedStaEvents(mDecodedProto);
    }

    /**
     * Ensure the number of StaEvents does not exceed MAX_STA_EVENTS by generating lots of events
     * and checking how many are deserialized
     */
    @Test
    public void testStaEventBounding() throws Exception {
        for (int i = 0; i < (WifiMetrics.MAX_STA_EVENTS + 10); i++) {
            mWifiMetrics.logStaEvent(StaEvent.TYPE_CMD_START_CONNECT);
        }
        dumpProtoAndDeserialize();
        assertEquals(WifiMetrics.MAX_STA_EVENTS, mDecodedProto.staEventList.length);
    }

    /**
     * Ensure WifiMetrics doesn't cause a null pointer exception when called with null args
     */
    @Test
    public void testDumpNullArg() {
        mWifiMetrics.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null);
    }

    /**
     * Test the generation of 'NumConnectableNetwork' histograms from two scans of different
     * ScanDetails produces the correct histogram values, and relevant bounds are observed
     */
    @Test
    public void testNumConnectableNetworksGeneration() throws Exception {
        List<ScanDetail> scan = new ArrayList<ScanDetail>();
        //                                ssid, bssid, isOpen, isSaved, isProvider, isWeakRssi)
        scan.add(buildMockScanDetail("PASSPOINT_1", "bssid0", false, false, true, false));
        scan.add(buildMockScanDetail("PASSPOINT_2", "bssid1", false, false, true, false));
        scan.add(buildMockScanDetail("SSID_B", "bssid2", true, true, false, false));
        scan.add(buildMockScanDetail("SSID_B", "bssid3", true, true, false, false));
        scan.add(buildMockScanDetail("SSID_C", "bssid4", true, false, false, false));
        scan.add(buildMockScanDetail("SSID_D", "bssid5", false, true, false, false));
        scan.add(buildMockScanDetail("SSID_E", "bssid6", false, true, false, false));
        scan.add(buildMockScanDetail("SSID_F", "bssid7", false, false, false, false));
        scan.add(buildMockScanDetail("SSID_G_WEAK", "bssid9", false, false, false, true));
        scan.add(buildMockScanDetail("SSID_H_WEAK", "bssid10", false, false, false, true));
        mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
        scan.add(buildMockScanDetail("SSID_B", "bssid8", true, true, false, false));
        mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
        for (int i = 0; i < NUM_PARTIAL_SCAN_RESULTS; i++) {
            mWifiMetrics.incrementAvailableNetworksHistograms(scan, false);
        }
        dumpProtoAndDeserialize();
        verifyHist(mDecodedProto.totalSsidsInScanHistogram, 1,                    a(7),    a(2));
        verifyHist(mDecodedProto.totalBssidsInScanHistogram, 2,                   a(8, 9), a(1, 1));
        verifyHist(mDecodedProto.availableOpenSsidsInScanHistogram, 1,            a(2),    a(2));
        verifyHist(mDecodedProto.availableOpenBssidsInScanHistogram, 2,           a(3, 4), a(1, 1));
        verifyHist(mDecodedProto.availableSavedSsidsInScanHistogram, 1,           a(3),    a(2));
        verifyHist(mDecodedProto.availableSavedBssidsInScanHistogram, 2,          a(4, 5), a(1, 1));
        verifyHist(mDecodedProto.availableOpenOrSavedSsidsInScanHistogram, 1,     a(4),    a(2));
        verifyHist(mDecodedProto.availableOpenOrSavedBssidsInScanHistogram, 2,    a(5, 6), a(1, 1));
        verifyHist(mDecodedProto.availableSavedPasspointProviderProfilesInScanHistogram, 1,
                                                                                  a(2),    a(2));
        verifyHist(mDecodedProto.availableSavedPasspointProviderBssidsInScanHistogram, 1,
                                                                                  a(2),    a(2));
        assertEquals(2, mDecodedProto.fullBandAllSingleScanListenerResults);
        assertEquals(NUM_PARTIAL_SCAN_RESULTS, mDecodedProto.partialAllSingleScanListenerResults);

        // Check Bounds
        scan.clear();
        int lotsOfSSids = Math.max(WifiMetrics.MAX_TOTAL_SCAN_RESULT_SSIDS_BUCKET,
                WifiMetrics.MAX_CONNECTABLE_SSID_NETWORK_BUCKET) + 5;
        for (int i = 0; i < lotsOfSSids; i++) {
            scan.add(buildMockScanDetail("SSID_" + i, "bssid_" + i, true, true, false, false));
        }
        mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
        dumpProtoAndDeserialize();
        verifyHist(mDecodedProto.totalSsidsInScanHistogram, 1,
                a(WifiMetrics.MAX_TOTAL_SCAN_RESULT_SSIDS_BUCKET), a(1));
        verifyHist(mDecodedProto.availableOpenSsidsInScanHistogram, 1,
                a(WifiMetrics.MAX_CONNECTABLE_SSID_NETWORK_BUCKET), a(1));
        verifyHist(mDecodedProto.availableSavedSsidsInScanHistogram, 1,
                a(WifiMetrics.MAX_CONNECTABLE_SSID_NETWORK_BUCKET), a(1));
        verifyHist(mDecodedProto.availableOpenOrSavedSsidsInScanHistogram, 1,
                a(WifiMetrics.MAX_CONNECTABLE_SSID_NETWORK_BUCKET), a(1));
        scan.clear();
        int lotsOfBssids = Math.max(WifiMetrics.MAX_TOTAL_SCAN_RESULTS_BUCKET,
                WifiMetrics.MAX_CONNECTABLE_BSSID_NETWORK_BUCKET) + 5;
        for (int i = 0; i < lotsOfBssids; i++) {
            scan.add(buildMockScanDetail("SSID", "bssid_" + i, true, true, false, false));
        }
        mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
        dumpProtoAndDeserialize();
        verifyHist(mDecodedProto.totalBssidsInScanHistogram, 1,
                a(WifiMetrics.MAX_TOTAL_SCAN_RESULTS_BUCKET), a(1));
        verifyHist(mDecodedProto.availableOpenBssidsInScanHistogram, 1,
                a(WifiMetrics.MAX_CONNECTABLE_BSSID_NETWORK_BUCKET), a(1));
        verifyHist(mDecodedProto.availableSavedBssidsInScanHistogram, 1,
                a(WifiMetrics.MAX_CONNECTABLE_BSSID_NETWORK_BUCKET), a(1));
        verifyHist(mDecodedProto.availableOpenOrSavedBssidsInScanHistogram, 1,
                a(WifiMetrics.MAX_CONNECTABLE_BSSID_NETWORK_BUCKET), a(1));
    }

    /** short hand for instantiating an anonymous int array, instead of 'new int[]{a1, a2, ...}' */
    private int[] a(int... element) {
        return element;
    }

    private void verifyHist(WifiMetricsProto.NumConnectableNetworksBucket[] hist, int size,
            int[] keys, int[] counts) throws Exception {
        assertEquals(size, hist.length);
        for (int i = 0; i < keys.length; i++) {
            assertEquals(keys[i], hist[i].numConnectableNetworks);
            assertEquals(counts[i], hist[i].count);
        }
    }

    /**
     * Generate an RSSI delta event by creating a connection event and an RSSI poll within
     * 'interArrivalTime' milliseconds of each other.
     * Event will not be logged if interArrivalTime > mWifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS
     * successfulConnectionEvent, completeConnectionEvent, useValidScanResult and
     * dontDeserializeBeforePoll
     * each create an anomalous condition when set to false.
     */
    private void generateRssiDelta(int scanRssi, int rssiDelta,
            long interArrivalTime, boolean successfulConnectionEvent,
            boolean completeConnectionEvent, boolean useValidScanResult,
            boolean dontDeserializeBeforePoll) throws Exception {
        when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 0);
        ScanResult scanResult = null;
        if (useValidScanResult) {
            scanResult = mock(ScanResult.class);
            scanResult.level = scanRssi;
        }
        WifiConfiguration config = mock(WifiConfiguration.class);
        WifiConfiguration.NetworkSelectionStatus networkSelectionStat =
                mock(WifiConfiguration.NetworkSelectionStatus.class);
        when(networkSelectionStat.getCandidate()).thenReturn(scanResult);
        when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStat);
        mWifiMetrics.startConnectionEvent(config, "TestNetwork",
                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
        if (completeConnectionEvent) {
            if (successfulConnectionEvent) {
                mWifiMetrics.endConnectionEvent(
                        WifiMetrics.ConnectionEvent.FAILURE_NONE,
                        WifiMetricsProto.ConnectionEvent.HLF_NONE);
            } else {
                mWifiMetrics.endConnectionEvent(
                        WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
                        WifiMetricsProto.ConnectionEvent.HLF_NONE);
            }
        }
        when(mClock.getElapsedSinceBootMillis()).thenReturn(interArrivalTime);
        if (!dontDeserializeBeforePoll) {
            dumpProtoAndDeserialize();
        }
        mWifiMetrics.incrementRssiPollRssiCount(scanRssi + rssiDelta);
    }

    /**
     * Generate an RSSI delta event, with all extra conditions set to true.
     */
    private void generateRssiDelta(int scanRssi, int rssiDelta,
            long interArrivalTime) throws Exception {
        generateRssiDelta(scanRssi, rssiDelta, interArrivalTime, true, true, true, true);
    }

    private void assertStringContains(
            String actualString, String expectedSubstring) {
        assertTrue("Expected text not found in: " + actualString,
                actualString.contains(expectedSubstring));
    }

    private String getStateDump() {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        PrintWriter writer = new PrintWriter(stream);
        String[] args = new String[0];
        mWifiMetrics.dump(null, writer, args);
        writer.flush();
        return stream.toString();
    }

    private static final int TEST_ALLOWED_KEY_MANAGEMENT = 83;
    private static final int TEST_ALLOWED_PROTOCOLS = 22;
    private static final int TEST_ALLOWED_AUTH_ALGORITHMS = 11;
    private static final int TEST_ALLOWED_PAIRWISE_CIPHERS = 67;
    private static final int TEST_ALLOWED_GROUP_CIPHERS = 231;
    private static final int TEST_CANDIDATE_LEVEL = -80;
    private static final int TEST_CANDIDATE_FREQ = 2345;

    private WifiConfiguration createComplexWifiConfig() {
        WifiConfiguration config = new WifiConfiguration();
        config.allowedKeyManagement = intToBitSet(TEST_ALLOWED_KEY_MANAGEMENT);
        config.allowedProtocols = intToBitSet(TEST_ALLOWED_PROTOCOLS);
        config.allowedAuthAlgorithms = intToBitSet(TEST_ALLOWED_AUTH_ALGORITHMS);
        config.allowedPairwiseCiphers = intToBitSet(TEST_ALLOWED_PAIRWISE_CIPHERS);
        config.allowedGroupCiphers = intToBitSet(TEST_ALLOWED_GROUP_CIPHERS);
        config.hiddenSSID = true;
        config.ephemeral = true;
        config.getNetworkSelectionStatus().setHasEverConnected(true);
        ScanResult candidate = new ScanResult();
        candidate.level = TEST_CANDIDATE_LEVEL;
        candidate.frequency = TEST_CANDIDATE_FREQ;
        config.getNetworkSelectionStatus().setCandidate(candidate);
        return config;
    }

    private void assertConfigInfoEqualsWifiConfig(WifiConfiguration config,
            StaEvent.ConfigInfo info) {
        if (config == null && info == null) return;
        assertEquals(config.allowedKeyManagement,   intToBitSet(info.allowedKeyManagement));
        assertEquals(config.allowedProtocols,       intToBitSet(info.allowedProtocols));
        assertEquals(config.allowedAuthAlgorithms,  intToBitSet(info.allowedAuthAlgorithms));
        assertEquals(config.allowedPairwiseCiphers, intToBitSet(info.allowedPairwiseCiphers));
        assertEquals(config.allowedGroupCiphers,    intToBitSet(info.allowedGroupCiphers));
        assertEquals(config.hiddenSSID, info.hiddenSsid);
        assertEquals(config.ephemeral, info.isEphemeral);
        assertEquals(config.getNetworkSelectionStatus().getHasEverConnected(),
                info.hasEverConnected);
        assertEquals(config.getNetworkSelectionStatus().getCandidate().level, info.scanRssi);
        assertEquals(config.getNetworkSelectionStatus().getCandidate().frequency, info.scanFreq);
    }

    /**
     * Sets the values of bitSet to match an int mask
     */
    private static BitSet intToBitSet(int mask) {
        BitSet bitSet = new BitSet();
        for (int bitIndex = 0; mask > 0; mask >>>= 1, bitIndex++) {
            if ((mask & 1) != 0) bitSet.set(bitIndex);
        }
        return bitSet;
    }
}
