WifiMetrics.java revision 46c84f9fd984cc4b67f5252e30bce7f756be558c
11b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne/*
21b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Copyright (C) 2016 The Android Open Source Project
31b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne *
41b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Licensed under the Apache License, Version 2.0 (the "License");
51b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * you may not use this file except in compliance with the License.
61b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * You may obtain a copy of the License at
71b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne *
81b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne *      http://www.apache.org/licenses/LICENSE-2.0
91b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne *
101b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Unless required by applicable law or agreed to in writing, software
111b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * distributed under the License is distributed on an "AS IS" BASIS,
121b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * See the License for the specific language governing permissions and
141b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * limitations under the License.
151b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */
161b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
171b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhnepackage com.android.server.wifi;
181b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
1946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
204569ebc2277f35b9bd1baa98194f963388e0c4caSohani Raoimport android.net.NetworkAgent;
214dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhneimport android.net.wifi.ScanResult;
2246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhneimport android.net.wifi.SupplicantState;
232532a24b254d724a9b6771d327dc410b32b18602Glen Kuhneimport android.net.wifi.WifiConfiguration;
2446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhneimport android.net.wifi.WifiInfo;
2544ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silbersteinimport android.net.wifi.WifiManager;
2646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhneimport android.os.Handler;
2746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhneimport android.os.Looper;
2846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhneimport android.os.Message;
291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport android.util.Base64;
30c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhneimport android.util.Log;
31c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhneimport android.util.SparseIntArray;
321b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
33f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhneimport com.android.server.wifi.hotspot2.NetworkDetail;
34da94688198c864bb29be2e9603ebbe9ae6492a87Tamas Berghammerimport com.android.server.wifi.nano.WifiMetricsProto;
3546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhneimport com.android.server.wifi.nano.WifiMetricsProto.StaEvent;
3646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhneimport com.android.server.wifi.nano.WifiMetricsProto.StaEvent.ConfigInfo;
37f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhneimport com.android.server.wifi.util.InformationElementUtil;
3859f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhneimport com.android.server.wifi.util.ScanResultUtil;
39f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne
401b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.io.FileDescriptor;
411b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.io.PrintWriter;
421b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.util.ArrayList;
4346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhneimport java.util.BitSet;
441b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.util.Calendar;
4546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhneimport java.util.LinkedList;
461b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.util.List;
471b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
481b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne/**
491b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Provides storage for wireless connectivity metrics, as they are generated.
501b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Metrics logged by this class include:
511b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne *   Aggregated connection stats (num of connections, num of failures, ...)
521b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne *   Discrete connection event stats (time, duration, failure codes, ...)
531b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne *   Router details (technology type, authentication type, ...)
541b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne *   Scan stats
551b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */
561b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhnepublic class WifiMetrics {
571b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    private static final String TAG = "WifiMetrics";
58c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private static final boolean DBG = false;
597a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    /**
607a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne     * Clamp the RSSI poll counts to values between [MIN,MAX]_RSSI_POLL
617a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne     */
627a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    private static final int MAX_RSSI_POLL = 0;
637a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    private static final int MIN_RSSI_POLL = -127;
645cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne    public static final int MAX_RSSI_DELTA = 127;
655cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne    public static final int MIN_RSSI_DELTA = -127;
665cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne    /** Maximum time period between ScanResult and RSSI poll to generate rssi delta datapoint */
675cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne    public static final long TIMEOUT_RSSI_DELTA_MILLIS =  3000;
684569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao    private static final int MIN_WIFI_SCORE = 0;
694569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao    private static final int MAX_WIFI_SCORE = NetworkAgent.WIFI_BASE_SCORE;
701b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    private final Object mLock = new Object();
712532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    private static final int MAX_CONNECTION_EVENTS = 256;
72107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne    private Clock mClock;
73ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    private boolean mScreenOn;
74ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    private int mWifiState;
7546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    private Handler mHandler;
761b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
771b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Metrics are stored within an instance of the WifiLog proto during runtime,
781b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * The ConnectionEvent, SystemStateEntries & ScanReturnEntries metrics are stored during
791b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * runtime in member lists of this WifiMetrics class, with the final WifiLog proto being pieced
801b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * together at dump-time
811b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
827a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    private final WifiMetricsProto.WifiLog mWifiLogProto = new WifiMetricsProto.WifiLog();
831b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
841b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Session information that gets logged for every Wifi connection attempt.
851b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
867a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    private final List<ConnectionEvent> mConnectionEventList = new ArrayList<>();
871b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
881b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * The latest started (but un-ended) connection attempt
891b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
901b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    private ConnectionEvent mCurrentConnectionEvent;
911b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
921b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Count of number of times each scan return code, indexed by WifiLog.ScanReturnCode
931b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
947a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    private final SparseIntArray mScanReturnEntries = new SparseIntArray();
951b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
961b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Mapping of system state to the counts of scans requested in that wifi state * screenOn
971b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * combination. Indexed by WifiLog.WifiState * (1 + screenOn)
981b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
997a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    private final SparseIntArray mWifiSystemStateEntries = new SparseIntArray();
100f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal    /** Mapping of RSSI values to counts. */
101f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal    private final SparseIntArray mRssiPollCounts = new SparseIntArray();
1025cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne    /** Mapping of RSSI scan-poll delta values to counts. */
1035cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne    private final SparseIntArray mRssiDeltaCounts = new SparseIntArray();
1045cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne    /** RSSI of the scan result for the last connection event*/
1055cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne    private int mScanResultRssi = 0;
1065cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne    /** Boot-relative timestamp when the last candidate scanresult was received, used to calculate
1075cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne        RSSI deltas. -1 designates no candidate scanResult being tracked */
1085cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne    private long mScanResultRssiTimestampMillis = -1;
109f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal    /** Mapping of alert reason to the respective alert count. */
110f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal    private final SparseIntArray mWifiAlertReasonCounts = new SparseIntArray();
111107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne    /**
112107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne     * Records the getElapsedSinceBootMillis (in seconds) that represents the beginning of data
113107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne     * capture for for this WifiMetricsProto
114107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne     */
115107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne    private long mRecordStartTimeSec;
1164569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao    /** Mapping of Wifi Scores to counts */
1174569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao    private final SparseIntArray mWifiScoreCounts = new SparseIntArray();
11844ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein    /** Mapping of SoftApManager start SoftAp return codes to counts */
11944ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein    private final SparseIntArray mSoftApManagerReturnCodeCounts = new SparseIntArray();
1201b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    class RouterFingerPrint {
1211b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        private WifiMetricsProto.RouterFingerPrint mRouterFingerPrintProto;
1222532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        RouterFingerPrint() {
1231b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mRouterFingerPrintProto = new WifiMetricsProto.RouterFingerPrint();
1241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
1251b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
1261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        public String toString() {
1271b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            StringBuilder sb = new StringBuilder();
1281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            synchronized (mLock) {
1291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append("mConnectionEvent.roamType=" + mRouterFingerPrintProto.roamType);
1301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mChannelInfo=" + mRouterFingerPrintProto.channelInfo);
1311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mDtim=" + mRouterFingerPrintProto.dtim);
1321b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mAuthentication=" + mRouterFingerPrintProto.authentication);
1331b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mHidden=" + mRouterFingerPrintProto.hidden);
1341b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mRouterTechnology=" + mRouterFingerPrintProto.routerTechnology);
1351b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mSupportsIpv6=" + mRouterFingerPrintProto.supportsIpv6);
1361b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
1371b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            return sb.toString();
1381b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
1392532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        public void updateFromWifiConfiguration(WifiConfiguration config) {
140ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne            synchronized (mLock) {
141ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                if (config != null) {
142ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // Is this a hidden network
143ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    mRouterFingerPrintProto.hidden = config.hiddenSSID;
144ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // Config may not have a valid dtimInterval set yet, in which case dtim will be zero
145ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // (These are only populated from beacon frame scan results, which are returned as
146ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // scan results from the chip far less frequently than Probe-responses)
147ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    if (config.dtimInterval > 0) {
148ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        mRouterFingerPrintProto.dtim = config.dtimInterval;
149ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    }
150ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    mCurrentConnectionEvent.mConfigSsid = config.SSID;
151ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // Get AuthType information from config (We do this again from ScanResult after
152ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // associating with BSSID)
153ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    if (config.allowedKeyManagement != null
154ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                            && config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) {
155ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
156ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                                .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_OPEN;
157ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    } else if (config.isEnterprise()) {
158ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
159ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                                .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE;
160ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    } else {
161ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
162ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                                .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL;
163ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    }
16459f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                    mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
16559f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                            .passpoint = config.isPasspoint();
166ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // If there's a ScanResult candidate associated with this config already, get it and
167ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // log (more accurate) metrics from it
168ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    ScanResult candidate = config.getNetworkSelectionStatus().getCandidate();
169ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    if (candidate != null) {
170ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        updateMetricsFromScanResult(candidate);
171ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    }
17296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                }
1732532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            }
1742532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        }
1751b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
1761b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
1771b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
1781b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Log event, tracking the start time, end time and result of a wireless connection attempt.
1791b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
1801b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    class ConnectionEvent {
1811b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        WifiMetricsProto.ConnectionEvent mConnectionEvent;
18296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        //<TODO> Move these constants into a wifi.proto Enum, and create a new Failure Type field
18396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        //covering more than just l2 failures. see b/27652362
18496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        /**
18596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne         * Failure codes, used for the 'level_2_failure_code' Connection event field (covers a lot
18696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne         * more failures than just l2 though, since the proto does not have a place to log
18796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne         * framework failures)
18896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne         */
1892532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // Failure is unknown
19096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_UNKNOWN = 0;
1912532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // NONE
19296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_NONE = 1;
1932532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // ASSOCIATION_REJECTION_EVENT
19496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_ASSOCIATION_REJECTION = 2;
1952532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // AUTHENTICATION_FAILURE_EVENT
19696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_AUTHENTICATION_FAILURE = 3;
1972532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // SSID_TEMP_DISABLED (Also Auth failure)
19896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_SSID_TEMP_DISABLED = 4;
1994dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        // reconnect() or reassociate() call to WifiNative failed
20096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_CONNECT_NETWORK_FAILED = 5;
2012532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // NETWORK_DISCONNECTION_EVENT
20296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_NETWORK_DISCONNECTION = 6;
2034dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        // NEW_CONNECTION_ATTEMPT before previous finished
20496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_NEW_CONNECTION_ATTEMPT = 7;
20596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        // New connection attempt to the same network & bssid
20696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_REDUNDANT_CONNECTION_ATTEMPT = 8;
20796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        // Roam Watchdog timer triggered (Roaming timed out)
20896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_ROAM_TIMEOUT = 9;
20996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        // DHCP failure
21096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_DHCP = 10;
21196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne
2124dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        RouterFingerPrint mRouterFingerPrint;
2134dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        private long mRealStartTime;
2144dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        private long mRealEndTime;
2154dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        private String mConfigSsid;
2164dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        private String mConfigBssid;
217ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        private int mWifiState;
218ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        private boolean mScreenOn;
2192532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne
2201b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        private ConnectionEvent() {
2211b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mConnectionEvent = new WifiMetricsProto.ConnectionEvent();
222947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne            mRealEndTime = 0;
223947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne            mRealStartTime = 0;
2242532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mRouterFingerPrint = new RouterFingerPrint();
2252532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mConnectionEvent.routerFingerprint = mRouterFingerPrint.mRouterFingerPrintProto;
2264dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mConfigSsid = "<NULL>";
2274dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mConfigBssid = "<NULL>";
228ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mWifiState = WifiMetricsProto.WifiLog.WIFI_UNKNOWN;
229ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mScreenOn = false;
2301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
2311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
2321b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        public String toString() {
2331b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            StringBuilder sb = new StringBuilder();
2341b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            sb.append("startTime=");
2351b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            Calendar c = Calendar.getInstance();
2361b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            synchronized (mLock) {
2371b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                c.setTimeInMillis(mConnectionEvent.startTimeMillis);
2381b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(mConnectionEvent.startTimeMillis == 0 ? "            <null>" :
2391b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c));
2404dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", SSID=");
2414dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(mConfigSsid);
2424dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", BSSID=");
2434dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(mConfigBssid);
2444dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", durationMillis=");
2451b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(mConnectionEvent.durationTakenToConnectMillis);
2462532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                sb.append(", roamType=");
2474dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                switch(mConnectionEvent.roamType) {
2482532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 1:
2492532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_NONE");
2502532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2512532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 2:
2522532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_DBDC");
2532532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2542532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 3:
2552532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_ENTERPRISE");
2562532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2572532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 4:
2582532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_USER_SELECTED");
2592532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2602532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 5:
2612532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_UNRELATED");
2622532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2632532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    default:
2642532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_UNKNOWN");
2652532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                }
2664dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", connectionResult=");
2674dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(mConnectionEvent.connectionResult);
2681b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", level2FailureCode=");
2694dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                switch(mConnectionEvent.level2FailureCode) {
27096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_NONE:
2714dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NONE");
2724dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
27396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_ASSOCIATION_REJECTION:
2744dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("ASSOCIATION_REJECTION");
2754dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
27696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_AUTHENTICATION_FAILURE:
2774dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("AUTHENTICATION_FAILURE");
2784dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
27996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_SSID_TEMP_DISABLED:
2804dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("SSID_TEMP_DISABLED");
2814dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
28296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_CONNECT_NETWORK_FAILED:
2834dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("CONNECT_NETWORK_FAILED");
2844dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
28596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_NETWORK_DISCONNECTION:
2864dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NETWORK_DISCONNECTION");
2874dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
28896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_NEW_CONNECTION_ATTEMPT:
2894dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NEW_CONNECTION_ATTEMPT");
2904dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
29196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_REDUNDANT_CONNECTION_ATTEMPT:
29296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        sb.append("REDUNDANT_CONNECTION_ATTEMPT");
29396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        break;
29496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_ROAM_TIMEOUT:
29596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        sb.append("ROAM_TIMEOUT");
29696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        break;
29796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_DHCP:
29896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        sb.append("DHCP");
2994dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    default:
3004dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("UNKNOWN");
3014dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
3024dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                }
3031b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", connectivityLevelFailureCode=");
3044dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                switch(mConnectionEvent.connectivityLevelFailureCode) {
3054dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    case WifiMetricsProto.ConnectionEvent.HLF_NONE:
3064dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NONE");
3074dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
3084dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    case WifiMetricsProto.ConnectionEvent.HLF_DHCP:
3094dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("DHCP");
3104dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
3114dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    case WifiMetricsProto.ConnectionEvent.HLF_NO_INTERNET:
3124dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NO_INTERNET");
3134dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
3144dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    case WifiMetricsProto.ConnectionEvent.HLF_UNWANTED:
3154dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("UNWANTED");
3164dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
3174dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    default:
3184dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("UNKNOWN");
3194dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
3204dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                }
3214dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", signalStrength=");
3224dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(mConnectionEvent.signalStrength);
323ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                sb.append(", wifiState=");
324ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                switch(mWifiState) {
325ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                    case WifiMetricsProto.WifiLog.WIFI_DISABLED:
326ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        sb.append("WIFI_DISABLED");
327ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        break;
328ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                    case WifiMetricsProto.WifiLog.WIFI_DISCONNECTED:
329ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        sb.append("WIFI_DISCONNECTED");
330ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        break;
331ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                    case WifiMetricsProto.WifiLog.WIFI_ASSOCIATED:
332ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        sb.append("WIFI_ASSOCIATED");
333ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        break;
334ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                    default:
335ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        sb.append("WIFI_UNKNOWN");
336ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        break;
337ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                }
338ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                sb.append(", screenOn=");
339ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                sb.append(mScreenOn);
340ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                sb.append(". mRouterFingerprint: ");
3411b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(mRouterFingerPrint.toString());
3421b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
3431b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            return sb.toString();
3441b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
3451b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
3461b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
34746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    public WifiMetrics(Clock clock, Looper looper) {
348107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne        mClock = clock;
3491b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        mCurrentConnectionEvent = null;
350ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        mScreenOn = true;
351ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        mWifiState = WifiMetricsProto.WifiLog.WIFI_DISABLED;
352107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne        mRecordStartTimeSec = mClock.getElapsedSinceBootMillis() / 1000;
35346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
35446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        mHandler = new Handler(looper) {
35546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            public void handleMessage(Message msg) {
35646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                synchronized (mLock) {
35746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                    processMessage(msg);
35846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                }
35946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            }
36046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        };
3611b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
3621b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
363c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    // Values used for indexing SystemStateEntries
364c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private static final int SCREEN_ON = 1;
365c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private static final int SCREEN_OFF = 0;
366c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
3671b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
3681b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Create a new connection event. Call when wifi attempts to make a new network connection
3691b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * If there is a current 'un-ended' connection event, it will be ended with UNKNOWN connectivity
3701b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * failure code.
3711b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Gathers and sets the RouterFingerPrint data as well
3721b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
373947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne     * @param config WifiConfiguration of the config used for the current connection attempt
3741b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param roamType Roam type that caused connection attempt, see WifiMetricsProto.WifiLog.ROAM_X
3751b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
37696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne    public void startConnectionEvent(WifiConfiguration config, String targetBSSID, int roamType) {
3771b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
37896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            // Check if this is overlapping another current connection event
37996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            if (mCurrentConnectionEvent != null) {
38096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                //Is this new Connection Event the same as the current one
38196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                if (mCurrentConnectionEvent.mConfigSsid != null
38296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        && mCurrentConnectionEvent.mConfigBssid != null
38396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        && config != null
38496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        && mCurrentConnectionEvent.mConfigSsid.equals(config.SSID)
38596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        && (mCurrentConnectionEvent.mConfigBssid.equals("any")
38696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        || mCurrentConnectionEvent.mConfigBssid.equals(targetBSSID))) {
38796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    mCurrentConnectionEvent.mConfigBssid = targetBSSID;
38896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    // End Connection Event due to new connection attempt to the same network
38996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    endConnectionEvent(ConnectionEvent.FAILURE_REDUNDANT_CONNECTION_ATTEMPT,
39096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                            WifiMetricsProto.ConnectionEvent.HLF_NONE);
39196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                } else {
39296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    // End Connection Event due to new connection attempt to different network
39396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    endConnectionEvent(ConnectionEvent.FAILURE_NEW_CONNECTION_ATTEMPT,
39496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                            WifiMetricsProto.ConnectionEvent.HLF_NONE);
39596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                }
39696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            }
39796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            //If past maximum connection events, start removing the oldest
3984dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            while(mConnectionEventList.size() >= MAX_CONNECTION_EVENTS) {
3994dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                mConnectionEventList.remove(0);
4004dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            }
4014dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mCurrentConnectionEvent = new ConnectionEvent();
4024dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mCurrentConnectionEvent.mConnectionEvent.startTimeMillis =
403107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne                    mClock.getWallClockMillis();
40496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            mCurrentConnectionEvent.mConfigBssid = targetBSSID;
4054dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mCurrentConnectionEvent.mConnectionEvent.roamType = roamType;
4064dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mCurrentConnectionEvent.mRouterFingerPrint.updateFromWifiConfiguration(config);
40796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            mCurrentConnectionEvent.mConfigBssid = "any";
408107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne            mCurrentConnectionEvent.mRealStartTime = mClock.getElapsedSinceBootMillis();
409ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mCurrentConnectionEvent.mWifiState = mWifiState;
410ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mCurrentConnectionEvent.mScreenOn = mScreenOn;
4114dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mConnectionEventList.add(mCurrentConnectionEvent);
4125cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne            mScanResultRssiTimestampMillis = -1;
4135cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne            if (config != null) {
4145cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                ScanResult candidate = config.getNetworkSelectionStatus().getCandidate();
4155cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                if (candidate != null) {
4165cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                    // Cache the RSSI of the candidate, as the connection event level is updated
4175cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                    // from other sources (polls, bssid_associations) and delta requires the
4185cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                    // scanResult rssi
4195cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                    mScanResultRssi = candidate.level;
4205cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                    mScanResultRssiTimestampMillis = mClock.getElapsedSinceBootMillis();
4215cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                }
4225cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne            }
4231b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
4241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
4251b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
4261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
4272532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne     * set the RoamType of the current ConnectionEvent (if any)
4282532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne     */
4292532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    public void setConnectionEventRoamType(int roamType) {
430ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne        synchronized (mLock) {
431ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne            if (mCurrentConnectionEvent != null) {
432ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.roamType = roamType;
433ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne            }
4342532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        }
4352532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    }
436f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne
437f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne    /**
438f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne     * Set AP related metrics from ScanDetail
439f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne     */
440f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne    public void setConnectionScanDetail(ScanDetail scanDetail) {
441ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne        synchronized (mLock) {
442ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne            if (mCurrentConnectionEvent != null && scanDetail != null) {
443ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                NetworkDetail networkDetail = scanDetail.getNetworkDetail();
444ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                ScanResult scanResult = scanDetail.getScanResult();
445ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                //Ensure that we have a networkDetail, and that it corresponds to the currently
446ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                //tracked connection attempt
447ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                if (networkDetail != null && scanResult != null
448ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        && mCurrentConnectionEvent.mConfigSsid != null
449ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        && mCurrentConnectionEvent.mConfigSsid
450ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        .equals("\"" + networkDetail.getSSID() + "\"")) {
451ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    updateMetricsFromNetworkDetail(networkDetail);
452ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    updateMetricsFromScanResult(scanResult);
453ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                }
454f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne            }
455f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne        }
456f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne    }
457f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne
4582532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    /**
4591b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * End a Connection event record. Call when wifi connection attempt succeeds or fails.
4601b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * If a Connection event has not been started and is active when .end is called, a new one is
4611b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * created with zero duration.
4621b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
4631b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param level2FailureCode Level 2 failure code returned by supplicant
4641b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param connectivityFailureCode WifiMetricsProto.ConnectionEvent.HLF_X
4651b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
4661b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void endConnectionEvent(int level2FailureCode, int connectivityFailureCode) {
4671b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
4682532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            if (mCurrentConnectionEvent != null) {
4692532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                boolean result = (level2FailureCode == 1)
4702532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        && (connectivityFailureCode == WifiMetricsProto.ConnectionEvent.HLF_NONE);
4712532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.connectionResult = result ? 1 : 0;
472107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne                mCurrentConnectionEvent.mRealEndTime = mClock.getElapsedSinceBootMillis();
4732532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.durationTakenToConnectMillis = (int)
4742532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        (mCurrentConnectionEvent.mRealEndTime
4752532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        - mCurrentConnectionEvent.mRealStartTime);
4762532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.level2FailureCode = level2FailureCode;
4772532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.connectivityLevelFailureCode =
4782532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        connectivityFailureCode;
479f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne                // ConnectionEvent already added to ConnectionEvents List. Safe to null current here
4802532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent = null;
4815cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                if (!result) {
4825cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                    mScanResultRssiTimestampMillis = -1;
4835cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                }
4841b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
4851b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
4861b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
4871b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
4882b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    /**
4892b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne     * Set ConnectionEvent DTIM Interval (if set), and 802.11 Connection mode, from NetworkDetail
4902b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne     */
4912b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    private void updateMetricsFromNetworkDetail(NetworkDetail networkDetail) {
4922b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        int dtimInterval = networkDetail.getDtimInterval();
4932b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        if (dtimInterval > 0) {
4942b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.dtim =
4952b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                    dtimInterval;
4962b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        }
4972b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        int connectionWifiMode;
4982b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        switch (networkDetail.getWifiMode()) {
4992b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_UNDEFINED:
5002b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_UNKNOWN;
5012b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
5022b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11A:
5032b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_A;
5042b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
5052b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11B:
5062b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_B;
5072b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
5082b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11G:
5092b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_G;
5102b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
5112b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11N:
5122b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_N;
5132b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
5142b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11AC  :
5152b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_AC;
5162b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
5172b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            default:
5182b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_OTHER;
5192b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
5202b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        }
5212b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
5222b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                .routerTechnology = connectionWifiMode;
5232b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    }
5242b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne
5252b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    /**
5262b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne     * Set ConnectionEvent RSSI and authentication type from ScanResult
5272b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne     */
5282b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    private void updateMetricsFromScanResult(ScanResult scanResult) {
5292b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        mCurrentConnectionEvent.mConnectionEvent.signalStrength = scanResult.level;
5302b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication =
5312b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                WifiMetricsProto.RouterFingerPrint.AUTH_OPEN;
53296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        mCurrentConnectionEvent.mConfigBssid = scanResult.BSSID;
5332b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        if (scanResult.capabilities != null) {
53459f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            if (ScanResultUtil.isScanResultForWepNetwork(scanResult)) {
5352b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication =
5362b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                        WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL;
53759f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            } else if (ScanResultUtil.isScanResultForPskNetwork(scanResult)) {
5382b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication =
5392b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                        WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL;
54059f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            } else if (ScanResultUtil.isScanResultForEapNetwork(scanResult)) {
5412b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication =
5422b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                        WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE;
5432b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            }
5442b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        }
54596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.channelInfo =
54696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                scanResult.frequency;
5472b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    }
5482b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne
5491b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setIsLocationEnabled(boolean enabled) {
5501b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5511b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.isLocationEnabled = enabled;
5521b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5531b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5541b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5551b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setIsScanningAlwaysEnabled(boolean enabled) {
5561b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5571b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.isScanningAlwaysEnabled = enabled;
5581b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5591b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5601b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5611b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
5621b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Increment Non Empty Scan Results count
5631b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
5641b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void incrementNonEmptyScanResultCount() {
565c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        if (DBG) Log.v(TAG, "incrementNonEmptyScanResultCount");
5661b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5671b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numNonEmptyScanResults++;
5681b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5691b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5701b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5711b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
5721b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Increment Empty Scan Results count
5731b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
5741b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void incrementEmptyScanResultCount() {
575c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        if (DBG) Log.v(TAG, "incrementEmptyScanResultCount");
5761b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5771b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numEmptyScanResults++;
5781b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5791b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5801b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5811b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
582c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Increment background scan count
583c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
584c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public void incrementBackgroundScanCount() {
585c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        if (DBG) Log.v(TAG, "incrementBackgroundScanCount");
586c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
587c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiLogProto.numBackgroundScans++;
588c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
589c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
590c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
591c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne   /**
592c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Get Background scan count
593c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
594c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public int getBackgroundScanCount() {
595c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
596c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            return mWifiLogProto.numBackgroundScans;
597c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
598c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
599c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
600c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
60170ce5a4cbaf5aaccd4e542e7bb87196fb4464a6eGlen Kuhne     * Increment oneshot scan count, and the associated WifiSystemScanStateCount entry
602c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
603c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public void incrementOneshotScanCount() {
604c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
605c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiLogProto.numOneshotScans++;
606c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
60770ce5a4cbaf5aaccd4e542e7bb87196fb4464a6eGlen Kuhne        incrementWifiSystemScanStateCount(mWifiState, mScreenOn);
608c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
609c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
610c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
611c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Get oneshot scan count
612c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
613c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public int getOneshotScanCount() {
614c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
615c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            return mWifiLogProto.numOneshotScans;
616c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
617c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
618c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
619c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private String returnCodeToString(int scanReturnCode) {
620c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        switch(scanReturnCode){
621c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.SCAN_UNKNOWN:
622c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "SCAN_UNKNOWN";
623c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.SCAN_SUCCESS:
624c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "SCAN_SUCCESS";
625c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED:
626c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "SCAN_FAILURE_INTERRUPTED";
627c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION:
628c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "SCAN_FAILURE_INVALID_CONFIGURATION";
629c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.FAILURE_WIFI_DISABLED:
630c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "FAILURE_WIFI_DISABLED";
631c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            default:
632c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "<UNKNOWN>";
633c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
634c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
635c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
636c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
6371b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Increment count of scan return code occurrence
6381b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
6391b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param scanReturnCode Return code from scan attempt WifiMetricsProto.WifiLog.SCAN_X
6401b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
641c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public void incrementScanReturnEntry(int scanReturnCode, int countToAdd) {
6421b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
643c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            if (DBG) Log.v(TAG, "incrementScanReturnEntry " + returnCodeToString(scanReturnCode));
644c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            int entry = mScanReturnEntries.get(scanReturnCode);
645c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            entry += countToAdd;
6461b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mScanReturnEntries.put(scanReturnCode, entry);
6471b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
6481b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
649c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
650c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Get the count of this scanReturnCode
651c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * @param scanReturnCode that we are getting the count for
652c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
653c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public int getScanReturnEntry(int scanReturnCode) {
654c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
655c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            return mScanReturnEntries.get(scanReturnCode);
656c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
657c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
658c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
659c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private String wifiSystemStateToString(int state) {
660c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        switch(state){
661c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.WIFI_UNKNOWN:
662c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "WIFI_UNKNOWN";
663c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.WIFI_DISABLED:
664c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "WIFI_DISABLED";
665c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.WIFI_DISCONNECTED:
666c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "WIFI_DISCONNECTED";
667c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.WIFI_ASSOCIATED:
668c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "WIFI_ASSOCIATED";
669c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            default:
670c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "default";
671c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
672c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
6731b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
6741b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
6751b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Increments the count of scans initiated by each wifi state, accounts for screenOn/Off
6761b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
6771b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param state State of the system when scan was initiated, see WifiMetricsProto.WifiLog.WIFI_X
6781b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param screenOn Is the screen on
6791b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
6801b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void incrementWifiSystemScanStateCount(int state, boolean screenOn) {
6811b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
682c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            if (DBG) {
683c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                Log.v(TAG, "incrementWifiSystemScanStateCount " + wifiSystemStateToString(state)
684c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + " " + screenOn);
6851b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
686c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            int index = (state * 2) + (screenOn ? SCREEN_ON : SCREEN_OFF);
687c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            int entry = mWifiSystemStateEntries.get(index);
688c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            entry++;
689c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiSystemStateEntries.put(index, entry);
690c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
691c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
692c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
693c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
694c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Get the count of this system State Entry
695c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
696c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public int getSystemStateCount(int state, boolean screenOn) {
697c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
698c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            int index = state * 2 + (screenOn ? SCREEN_ON : SCREEN_OFF);
699c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            return mWifiSystemStateEntries.get(index);
7001b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
7011b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
7021b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
703ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    /**
7045f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment number of times the Watchdog of Last Resort triggered, resetting the wifi stack
7055f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7065f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggers() {
7075f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7085f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggers++;
7095f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7105f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7115f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7125f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks over bad association threshold when watchdog triggered
7135f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7145f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogBadAssociationNetworksTotal(int count) {
7155f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7165f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal += count;
7175f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7185f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7195f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7205f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks over bad authentication threshold when watchdog triggered
7215f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7225f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogBadAuthenticationNetworksTotal(int count) {
7235f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7245f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal += count;
7255f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7265f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7275f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7285f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks over bad dhcp threshold when watchdog triggered
7295f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7305f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogBadDhcpNetworksTotal(int count) {
7315f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7325f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal += count;
7335f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7345f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7355f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7365f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks over bad other threshold when watchdog triggered
7375f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7385f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogBadOtherNetworksTotal(int count) {
7395f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7405f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal += count;
7415f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7425f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7435f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7445f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks seen when watchdog triggered
7455f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7465f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogAvailableNetworksTotal(int count) {
7475f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7485f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal += count;
7495f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7505f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7515f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7525f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment count of triggers with atleast one bad association network
7535f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7545f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggersWithBadAssociation() {
7555f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7565f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation++;
7575f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7585f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7595f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7605f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment count of triggers with atleast one bad authentication network
7615f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7625f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggersWithBadAuthentication() {
7635f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7645f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication++;
7655f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7665f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7675f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7685f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment count of triggers with atleast one bad dhcp network
7695f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7705f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggersWithBadDhcp() {
7715f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7725f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp++;
7735f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7745f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7755f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7765f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment count of triggers with atleast one bad other network
7775f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7785f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggersWithBadOther() {
7795f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7805f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggersWithBadOther++;
7815f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7825f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7835f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne
7845f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
785ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     * Increment number of times connectivity watchdog confirmed pno is working
786ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     */
787ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    public void incrementNumConnectivityWatchdogPnoGood() {
788ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        synchronized (mLock) {
789ce003b812aead64dcb36647180991150021b24c1Glen Kuhne            mWifiLogProto.numConnectivityWatchdogPnoGood++;
790ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        }
791ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    }
792ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    /**
793ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     * Increment number of times connectivity watchdog found pno not working
794ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     */
795ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    public void incrementNumConnectivityWatchdogPnoBad() {
796ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        synchronized (mLock) {
797ce003b812aead64dcb36647180991150021b24c1Glen Kuhne            mWifiLogProto.numConnectivityWatchdogPnoBad++;
798ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        }
799ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    }
800ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    /**
801ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     * Increment number of times connectivity watchdog confirmed background scan is working
802ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     */
803ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    public void incrementNumConnectivityWatchdogBackgroundGood() {
804ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        synchronized (mLock) {
805ce003b812aead64dcb36647180991150021b24c1Glen Kuhne            mWifiLogProto.numConnectivityWatchdogBackgroundGood++;
806ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        }
807ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    }
808ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    /**
809ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     * Increment number of times connectivity watchdog found background scan not working
810ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     */
811ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    public void incrementNumConnectivityWatchdogBackgroundBad() {
812ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        synchronized (mLock) {
813ce003b812aead64dcb36647180991150021b24c1Glen Kuhne            mWifiLogProto.numConnectivityWatchdogBackgroundBad++;
814ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        }
815ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    }
816ce003b812aead64dcb36647180991150021b24c1Glen Kuhne
8177a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    /**
81846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * Increment various poll related metrics, and cache performance data for StaEvent logging
81946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     */
82046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    public void handlePollResult(WifiInfo wifiInfo) {
82146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        mLastPollRssi = wifiInfo.getRssi();
82246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        mLastPollLinkSpeed = wifiInfo.getLinkSpeed();
82346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        mLastPollFreq = wifiInfo.getFrequency();
82446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        incrementRssiPollRssiCount(mLastPollRssi);
82546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
82646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
82746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    /**
8287a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne     * Increment occurence count of RSSI level from RSSI poll.
8297a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne     * Ignores rssi values outside the bounds of [MIN_RSSI_POLL, MAX_RSSI_POLL]
8307a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne     */
8317a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    public void incrementRssiPollRssiCount(int rssi) {
8327a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne        if (!(rssi >= MIN_RSSI_POLL && rssi <= MAX_RSSI_POLL)) {
8337a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            return;
8347a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne        }
8357a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne        synchronized (mLock) {
8367a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            int count = mRssiPollCounts.get(rssi);
8377a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            mRssiPollCounts.put(rssi, count + 1);
8385cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne            maybeIncrementRssiDeltaCount(rssi - mScanResultRssi);
8395cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne        }
8405cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne    }
8415cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne
8425cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne    /**
8435cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne     * Increment occurence count of difference between scan result RSSI and the first RSSI poll.
8445cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne     * Ignores rssi values outside the bounds of [MIN_RSSI_DELTA, MAX_RSSI_DELTA]
8455cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne     * mLock must be held when calling this method.
8465cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne     */
8475cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne    private void maybeIncrementRssiDeltaCount(int rssi) {
8485cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne        // Check if this RSSI poll is close enough to a scan result RSSI to log a delta value
8495cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne        if (mScanResultRssiTimestampMillis >= 0) {
8505cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne            long timeDelta = mClock.getElapsedSinceBootMillis() - mScanResultRssiTimestampMillis;
8515cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne            if (timeDelta <= TIMEOUT_RSSI_DELTA_MILLIS) {
8525cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                if (rssi >= MIN_RSSI_DELTA && rssi <= MAX_RSSI_DELTA) {
8535cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                    int count = mRssiDeltaCounts.get(rssi);
8545cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                    mRssiDeltaCounts.put(rssi, count + 1);
8555cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                }
8565cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne            }
8575cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne            mScanResultRssiTimestampMillis = -1;
8587a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne        }
8597a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    }
8607a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne
861da22e3d28b62005dce5fddd75207bd3d7a1745e1Glen Kuhne    /**
8621c50de232acb3d6148c454941a6b9a79e0663b81Glen Kuhne     * Increment count of Watchdog successes.
8631c50de232acb3d6148c454941a6b9a79e0663b81Glen Kuhne     */
8641c50de232acb3d6148c454941a6b9a79e0663b81Glen Kuhne    public void incrementNumLastResortWatchdogSuccesses() {
8651c50de232acb3d6148c454941a6b9a79e0663b81Glen Kuhne        synchronized (mLock) {
8661c50de232acb3d6148c454941a6b9a79e0663b81Glen Kuhne            mWifiLogProto.numLastResortWatchdogSuccesses++;
8671c50de232acb3d6148c454941a6b9a79e0663b81Glen Kuhne        }
8681c50de232acb3d6148c454941a6b9a79e0663b81Glen Kuhne    }
8691c50de232acb3d6148c454941a6b9a79e0663b81Glen Kuhne
8701c50de232acb3d6148c454941a6b9a79e0663b81Glen Kuhne    /**
871f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal     * Increments the count of alerts by alert reason.
872f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal     *
873f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal     * @param reason The cause of the alert. The reason values are driver-specific.
874f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal     */
875f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal    public void incrementAlertReasonCount(int reason) {
876f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal        if (reason > WifiLoggerHal.WIFI_ALERT_REASON_MAX
877f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                || reason < WifiLoggerHal.WIFI_ALERT_REASON_MIN) {
878f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            reason = WifiLoggerHal.WIFI_ALERT_REASON_RESERVED;
879f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal        }
880f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal        synchronized (mLock) {
881f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            int alertCount = mWifiAlertReasonCounts.get(reason);
882f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            mWifiAlertReasonCounts.put(reason, alertCount + 1);
883f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal        }
884f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal    }
885f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal
886f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal    /**
88759f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne     * Counts all the different types of networks seen in a set of scan results
88859f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne     */
88959f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne    public void countScanResults(List<ScanDetail> scanDetails) {
89059f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne        if (scanDetails == null) {
89159f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            return;
89259f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne        }
89359f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne        int totalResults = 0;
89459f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne        int openNetworks = 0;
89559f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne        int personalNetworks = 0;
89659f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne        int enterpriseNetworks = 0;
89759f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne        int hiddenNetworks = 0;
89859f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne        int hotspot2r1Networks = 0;
89959f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne        int hotspot2r2Networks = 0;
90059f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne        for (ScanDetail scanDetail : scanDetails) {
90159f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            NetworkDetail networkDetail = scanDetail.getNetworkDetail();
90259f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            ScanResult scanResult = scanDetail.getScanResult();
90359f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            totalResults++;
90459f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            if (networkDetail != null) {
90559f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                if (networkDetail.isHiddenBeaconFrame()) {
90659f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                    hiddenNetworks++;
90759f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                }
90859f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                if (networkDetail.getHSRelease() != null) {
90959f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                    if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R1) {
91059f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                        hotspot2r1Networks++;
91159f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                    } else if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R2) {
91259f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                        hotspot2r2Networks++;
91359f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                    }
91459f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                }
91559f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            }
91659f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            if (scanResult != null && scanResult.capabilities != null) {
91759f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                if (ScanResultUtil.isScanResultForEapNetwork(scanResult)) {
91859f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                    enterpriseNetworks++;
91959f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                } else if (ScanResultUtil.isScanResultForPskNetwork(scanResult)
92059f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                        || ScanResultUtil.isScanResultForWepNetwork(scanResult)) {
92159f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                    personalNetworks++;
92259f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                } else {
92359f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                    openNetworks++;
92459f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                }
92559f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            }
92659f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne        }
92759f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne        synchronized (mLock) {
92859f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            mWifiLogProto.numTotalScanResults += totalResults;
92959f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            mWifiLogProto.numOpenNetworkScanResults += openNetworks;
93059f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            mWifiLogProto.numPersonalNetworkScanResults += personalNetworks;
93159f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            mWifiLogProto.numEnterpriseNetworkScanResults += enterpriseNetworks;
93259f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            mWifiLogProto.numHiddenNetworkScanResults += hiddenNetworks;
93359f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            mWifiLogProto.numHotspot2R1NetworkScanResults += hotspot2r1Networks;
93459f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            mWifiLogProto.numHotspot2R2NetworkScanResults += hotspot2r2Networks;
93559f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne            mWifiLogProto.numScans++;
93659f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne        }
93759f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne    }
93859f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne
93959f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne    /**
9404569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao     * Increments occurence of a particular wifi score calculated
9414569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao     * in WifiScoreReport by current connected network. Scores are bounded
9424569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao     * within  [MIN_WIFI_SCORE, MAX_WIFI_SCORE] to limit size of SparseArray
9434569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao     */
9444569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao    public void incrementWifiScoreCount(int score) {
9454569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao        if (score < MIN_WIFI_SCORE || score > MAX_WIFI_SCORE) {
9464569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao            return;
9474569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao        }
9484569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao        synchronized (mLock) {
9494569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao            int count = mWifiScoreCounts.get(score);
9504569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao            mWifiScoreCounts.put(score, count + 1);
9514569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao        }
9524569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao    }
95359f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne
95444ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein    /**
95544ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein     * Increments occurence of the results from attempting to start SoftAp.
95644ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein     * Maps the |result| and WifiManager |failureCode| constant to proto defined SoftApStartResult
95744ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein     * codes.
95844ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein     */
95944ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein    public void incrementSoftApStartResult(boolean result, int failureCode) {
96044ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein        synchronized (mLock) {
96144ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein            if (result) {
96244ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                int count = mSoftApManagerReturnCodeCounts.get(
96344ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_STARTED_SUCCESSFULLY);
96444ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                mSoftApManagerReturnCodeCounts.put(
96544ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_STARTED_SUCCESSFULLY,
96644ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        count + 1);
96744ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                return;
96844ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein            }
96944ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein
97044ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein            // now increment failure modes - if not explicitly handled, dump into the general
97144ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein            // error bucket.
97244ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein            if (failureCode == WifiManager.SAP_START_FAILURE_NO_CHANNEL) {
97344ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                int count = mSoftApManagerReturnCodeCounts.get(
97444ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_NO_CHANNEL);
97544ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                mSoftApManagerReturnCodeCounts.put(
97644ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_NO_CHANNEL,
97744ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        count + 1);
97844ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein            } else {
97944ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                // failure mode not tracked at this time...  count as a general error for now.
98044ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                int count = mSoftApManagerReturnCodeCounts.get(
98144ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_GENERAL_ERROR);
98244ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                mSoftApManagerReturnCodeCounts.put(
98344ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_GENERAL_ERROR,
98444ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        count + 1);
98544ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein            }
98644ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein        }
98744ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein    }
98844ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein
98911638f348ba45f9f417928e79b81186cef76c561Glen Kuhne    public static final String PROTO_DUMP_ARG = "wifiMetricsProto";
9909ff7dea01b09f658492b7b8fa122695e56d28cdcGlen Kuhne    public static final String CLEAN_DUMP_ARG = "clean";
9919ff7dea01b09f658492b7b8fa122695e56d28cdcGlen Kuhne
9921b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
9931b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Dump all WifiMetrics. Collects some metrics from ConfigStore, Settings and WifiManager
9949ff7dea01b09f658492b7b8fa122695e56d28cdcGlen Kuhne     * at this time.
9951b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
9961b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param fd unused
9971b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param pw PrintWriter for writing dump to
9981b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param args unused
9991b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
10001b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10011b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
100211638f348ba45f9f417928e79b81186cef76c561Glen Kuhne            if (args.length > 0 && PROTO_DUMP_ARG.equals(args[0])) {
10039ff7dea01b09f658492b7b8fa122695e56d28cdcGlen Kuhne                // Dump serialized WifiLog proto
10041b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                consolidateProto(true);
10051b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                for (ConnectionEvent event : mConnectionEventList) {
10061b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    if (mCurrentConnectionEvent != event) {
10071b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        //indicate that automatic bug report has been taken for all valid
10081b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        //connection events
10091b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        event.mConnectionEvent.automaticBugReportTaken = true;
10101b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    }
10111b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                }
10121b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                byte[] wifiMetricsProto = WifiMetricsProto.WifiLog.toByteArray(mWifiLogProto);
10131b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                String metricsProtoDump = Base64.encodeToString(wifiMetricsProto, Base64.DEFAULT);
10149ff7dea01b09f658492b7b8fa122695e56d28cdcGlen Kuhne                if (args.length > 1 && CLEAN_DUMP_ARG.equals(args[1])) {
10159ff7dea01b09f658492b7b8fa122695e56d28cdcGlen Kuhne                    // Output metrics proto bytes (base64) and nothing else
10169ff7dea01b09f658492b7b8fa122695e56d28cdcGlen Kuhne                    pw.print(metricsProtoDump);
10179ff7dea01b09f658492b7b8fa122695e56d28cdcGlen Kuhne                } else {
10189ff7dea01b09f658492b7b8fa122695e56d28cdcGlen Kuhne                    // Tag the start and end of the metrics proto bytes
10199ff7dea01b09f658492b7b8fa122695e56d28cdcGlen Kuhne                    pw.println("WifiMetrics:");
10209ff7dea01b09f658492b7b8fa122695e56d28cdcGlen Kuhne                    pw.println(metricsProtoDump);
10219ff7dea01b09f658492b7b8fa122695e56d28cdcGlen Kuhne                    pw.println("EndWifiMetrics");
10229ff7dea01b09f658492b7b8fa122695e56d28cdcGlen Kuhne                }
10232532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                clear();
10241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            } else {
10259ff7dea01b09f658492b7b8fa122695e56d28cdcGlen Kuhne                pw.println("WifiMetrics:");
10261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mConnectionEvents:");
10271b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                for (ConnectionEvent event : mConnectionEventList) {
10281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    String eventLine = event.toString();
10291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    if (event == mCurrentConnectionEvent) {
10301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        eventLine += "CURRENTLY OPEN EVENT";
10311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    }
10321b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    pw.println(eventLine);
10331b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                }
10341b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.numSavedNetworks=" + mWifiLogProto.numSavedNetworks);
10351b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.numOpenNetworks=" + mWifiLogProto.numOpenNetworks);
10361b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.numPersonalNetworks="
10371b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        + mWifiLogProto.numPersonalNetworks);
10381b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.numEnterpriseNetworks="
10391b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        + mWifiLogProto.numEnterpriseNetworks);
104059f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                pw.println("mWifiLogProto.numHiddenNetworks=" + mWifiLogProto.numHiddenNetworks);
104159f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                pw.println("mWifiLogProto.numPasspointNetworks="
104259f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                        + mWifiLogProto.numPasspointNetworks);
10431b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.isLocationEnabled=" + mWifiLogProto.isLocationEnabled);
10441b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.isScanningAlwaysEnabled="
10451b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        + mWifiLogProto.isScanningAlwaysEnabled);
1046c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numNetworksAddedByUser="
1047c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numNetworksAddedByUser);
1048c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numNetworksAddedByApps="
1049c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numNetworksAddedByApps);
1050c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numNonEmptyScanResults="
1051c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numNonEmptyScanResults);
1052c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numEmptyScanResults="
1053c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numEmptyScanResults);
1054c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numOneshotScans="
1055c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numOneshotScans);
1056c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numBackgroundScans="
1057c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numBackgroundScans);
1058c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
1059c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mScanReturnEntries:");
1060c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  SCAN_UNKNOWN: " + getScanReturnEntry(
1061c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.SCAN_UNKNOWN));
1062c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  SCAN_SUCCESS: " + getScanReturnEntry(
1063c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.SCAN_SUCCESS));
1064c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  SCAN_FAILURE_INTERRUPTED: " + getScanReturnEntry(
1065c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED));
1066c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  SCAN_FAILURE_INVALID_CONFIGURATION: " + getScanReturnEntry(
1067c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION));
1068c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  FAILURE_WIFI_DISABLED: " + getScanReturnEntry(
1069c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.FAILURE_WIFI_DISABLED));
1070c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
1071c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mSystemStateEntries: <state><screenOn> : <scansInitiated>");
1072c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_UNKNOWN       ON: "
1073c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, true));
1074c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_DISABLED      ON: "
1075c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISABLED, true));
1076c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_DISCONNECTED  ON: "
1077c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED, true));
1078c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_ASSOCIATED    ON: "
1079c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, true));
1080c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_UNKNOWN      OFF: "
1081c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, false));
1082c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_DISABLED     OFF: "
1083c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISABLED, false));
1084c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_DISCONNECTED OFF: "
1085c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED, false));
1086c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_ASSOCIATED   OFF: "
1087c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, false));
1088ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                pw.println("mWifiLogProto.numConnectivityWatchdogPnoGood="
1089ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                        + mWifiLogProto.numConnectivityWatchdogPnoGood);
1090ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                pw.println("mWifiLogProto.numConnectivityWatchdogPnoBad="
1091ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                        + mWifiLogProto.numConnectivityWatchdogPnoBad);
1092ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                pw.println("mWifiLogProto.numConnectivityWatchdogBackgroundGood="
1093ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                        + mWifiLogProto.numConnectivityWatchdogBackgroundGood);
1094ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                pw.println("mWifiLogProto.numConnectivityWatchdogBackgroundBad="
1095ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                        + mWifiLogProto.numConnectivityWatchdogBackgroundBad);
10965f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggers="
10975f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggers);
10985f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal="
10995f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal);
11005f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal="
11015f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal);
11025f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal="
11035f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal);
11045f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal="
11055f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal);
11065f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal="
11075f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal);
11085f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation="
11095f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation);
11105f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication="
11115f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication);
11125f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp="
11135f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp);
11145f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadOther="
11155f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggersWithBadOther);
1116da22e3d28b62005dce5fddd75207bd3d7a1745e1Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogSuccesses="
1117da22e3d28b62005dce5fddd75207bd3d7a1745e1Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogSuccesses);
1118107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne                pw.println("mWifiLogProto.recordDurationSec="
1119107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne                        + ((mClock.getElapsedSinceBootMillis() / 1000) - mRecordStartTimeSec));
11207a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                pw.println("mWifiLogProto.rssiPollRssiCount: Printing counts for [" + MIN_RSSI_POLL
11217a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                        + ", " + MAX_RSSI_POLL + "]");
11227a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                StringBuilder sb = new StringBuilder();
11237a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                for (int i = MIN_RSSI_POLL; i <= MAX_RSSI_POLL; i++) {
11247a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                    sb.append(mRssiPollCounts.get(i) + " ");
11257a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                }
11267a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                pw.println("  " + sb.toString());
11275cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                pw.println("mWifiLogProto.rssiPollDeltaCount: Printing counts for ["
11285cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                        + MIN_RSSI_DELTA + ", " + MAX_RSSI_DELTA + "]");
11295cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                sb.setLength(0);
11305cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                for (int i = MIN_RSSI_DELTA; i <= MAX_RSSI_DELTA; i++) {
11315cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                    sb.append(mRssiDeltaCounts.get(i) + " ");
11325cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                }
11335cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                pw.println("  " + sb.toString());
1134f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                pw.print("mWifiLogProto.alertReasonCounts=");
1135f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                sb.setLength(0);
1136f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                for (int i = WifiLoggerHal.WIFI_ALERT_REASON_MIN;
1137f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                        i <= WifiLoggerHal.WIFI_ALERT_REASON_MAX; i++) {
1138f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                    int count = mWifiAlertReasonCounts.get(i);
1139f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                    if (count > 0) {
1140f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                        sb.append("(" + i + "," + count + "),");
1141f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                    }
1142f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                }
1143f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                if (sb.length() > 1) {
1144f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                    sb.setLength(sb.length() - 1);  // strip trailing comma
1145f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                    pw.println(sb.toString());
1146f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                } else {
1147f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                    pw.println("()");
1148f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                }
114959f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                pw.println("mWifiLogProto.numTotalScanResults="
115059f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                        + mWifiLogProto.numTotalScanResults);
115159f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                pw.println("mWifiLogProto.numOpenNetworkScanResults="
115259f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                        + mWifiLogProto.numOpenNetworkScanResults);
115359f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                pw.println("mWifiLogProto.numPersonalNetworkScanResults="
115459f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                        + mWifiLogProto.numPersonalNetworkScanResults);
115559f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                pw.println("mWifiLogProto.numEnterpriseNetworkScanResults="
115659f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                        + mWifiLogProto.numEnterpriseNetworkScanResults);
115759f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                pw.println("mWifiLogProto.numHiddenNetworkScanResults="
115859f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                        + mWifiLogProto.numHiddenNetworkScanResults);
115959f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                pw.println("mWifiLogProto.numHotspot2R1NetworkScanResults="
116059f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                        + mWifiLogProto.numHotspot2R1NetworkScanResults);
116159f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                pw.println("mWifiLogProto.numHotspot2R2NetworkScanResults="
116259f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                        + mWifiLogProto.numHotspot2R2NetworkScanResults);
116359f9a74676831ba4634b35d56a1e2bbe9bf4e322Glen Kuhne                pw.println("mWifiLogProto.numScans=" + mWifiLogProto.numScans);
11644569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao                pw.println("mWifiLogProto.WifiScoreCount: [" + MIN_WIFI_SCORE + ", "
11654569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao                        + MAX_WIFI_SCORE + "]");
11664569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao                for (int i = 0; i <= MAX_WIFI_SCORE; i++) {
11674569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao                    pw.print(mWifiScoreCounts.get(i) + " ");
11684569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao                }
116944ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                pw.println(); // add a line after wifi scores
117044ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                pw.println("mWifiLogProto.SoftApManagerReturnCodeCounts:");
117144ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                pw.println("  SUCCESS: " + mSoftApManagerReturnCodeCounts.get(
117244ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_STARTED_SUCCESSFULLY));
117344ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                pw.println("  FAILED_GENERAL_ERROR: " + mSoftApManagerReturnCodeCounts.get(
117444ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_GENERAL_ERROR));
117544ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                pw.println("  FAILED_NO_CHANNEL: " + mSoftApManagerReturnCodeCounts.get(
117644ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_NO_CHANNEL));
11774569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao                pw.print("\n");
117846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                pw.println("StaEventList:");
117946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                for (StaEvent event : mStaEventList) {
118046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                    pw.println(staEventToString(event));
118146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                }
11821b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
11831b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
11841b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
11851b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
11863c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne
11873c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne    /**
11883c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne     * Update various counts of saved network types
11893c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne     * @param networks List of WifiConfigurations representing all saved networks, must not be null
11903c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne     */
11913c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne    public void updateSavedNetworks(List<WifiConfiguration> networks) {
11923c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne        synchronized (mLock) {
11933c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne            mWifiLogProto.numSavedNetworks = networks.size();
11943c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne            mWifiLogProto.numOpenNetworks = 0;
11953c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne            mWifiLogProto.numPersonalNetworks = 0;
11963c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne            mWifiLogProto.numEnterpriseNetworks = 0;
11973c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne            mWifiLogProto.numNetworksAddedByUser = 0;
11983c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne            mWifiLogProto.numNetworksAddedByApps = 0;
11993c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne            mWifiLogProto.numHiddenNetworks = 0;
12003c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne            mWifiLogProto.numPasspointNetworks = 0;
12013c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne            for (WifiConfiguration config : networks) {
12023c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) {
12033c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                    mWifiLogProto.numOpenNetworks++;
12043c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                } else if (config.isEnterprise()) {
12053c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                    mWifiLogProto.numEnterpriseNetworks++;
12063c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                } else {
12073c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                    mWifiLogProto.numPersonalNetworks++;
12083c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                }
12093c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                if (config.selfAdded) {
12103c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                    mWifiLogProto.numNetworksAddedByUser++;
12113c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                } else {
12123c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                    mWifiLogProto.numNetworksAddedByApps++;
12133c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                }
12143c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                if (config.hiddenSSID) {
12153c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                    mWifiLogProto.numHiddenNetworks++;
12163c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                }
12173c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                if (config.isPasspoint()) {
12183c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                    mWifiLogProto.numPasspointNetworks++;
12193c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne                }
12203c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne            }
12213c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne        }
12223c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne    }
12233c6e92f51984ba8999d5efe622b4a52dd18bdaffGlen Kuhne
12241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
1225c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * append the separate ConnectionEvent, SystemStateEntry and ScanReturnCode collections to their
1226c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * respective lists within mWifiLogProto
12271b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
12281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param incremental Only include ConnectionEvents created since last automatic bug report
12291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
12301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    private void consolidateProto(boolean incremental) {
12311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        List<WifiMetricsProto.ConnectionEvent> events = new ArrayList<>();
12327a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne        List<WifiMetricsProto.RssiPollCount> rssis = new ArrayList<>();
12335cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne        List<WifiMetricsProto.RssiPollCount> rssiDeltas = new ArrayList<>();
1234f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal        List<WifiMetricsProto.AlertReasonCount> alertReasons = new ArrayList<>();
12354569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao        List<WifiMetricsProto.WifiScoreCount> scores = new ArrayList<>();
12361b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
12371b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            for (ConnectionEvent event : mConnectionEventList) {
1238c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                // If this is not incremental, dump full ConnectionEvent list
1239c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                // Else Dump all un-dumped events except for the current one
12401b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                if (!incremental || ((mCurrentConnectionEvent != event)
12411b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        && !event.mConnectionEvent.automaticBugReportTaken)) {
12421b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    //Get all ConnectionEvents that haven not been dumped as a proto, also exclude
12431b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    //the current active un-ended connection event
12441b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    events.add(event.mConnectionEvent);
1245c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    if (incremental) {
1246c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        event.mConnectionEvent.automaticBugReportTaken = true;
1247c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    }
12481b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                }
12491b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
12501b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            if (events.size() > 0) {
12511b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                mWifiLogProto.connectionEvent = events.toArray(mWifiLogProto.connectionEvent);
12521b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
1253c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
1254c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            //Convert the SparseIntArray of scanReturnEntry integers into ScanReturnEntry proto list
1255c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiLogProto.scanReturnEntries =
1256c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    new WifiMetricsProto.WifiLog.ScanReturnEntry[mScanReturnEntries.size()];
1257c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            for (int i = 0; i < mScanReturnEntries.size(); i++) {
1258c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.scanReturnEntries[i] = new WifiMetricsProto.WifiLog.ScanReturnEntry();
1259c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.scanReturnEntries[i].scanReturnCode = mScanReturnEntries.keyAt(i);
1260c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.scanReturnEntries[i].scanResultsCount = mScanReturnEntries.valueAt(i);
1261c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            }
1262c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
1263c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            // Convert the SparseIntArray of systemStateEntry into WifiSystemStateEntry proto list
1264c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            // This one is slightly more complex, as the Sparse are indexed with:
1265c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            //     key: wifiState * 2 + isScreenOn, value: wifiStateCount
1266c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiLogProto.wifiSystemStateEntries =
1267c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    new WifiMetricsProto.WifiLog
1268c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    .WifiSystemStateEntry[mWifiSystemStateEntries.size()];
1269c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            for (int i = 0; i < mWifiSystemStateEntries.size(); i++) {
1270c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.wifiSystemStateEntries[i] =
1271c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        new WifiMetricsProto.WifiLog.WifiSystemStateEntry();
1272c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.wifiSystemStateEntries[i].wifiState =
1273c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        mWifiSystemStateEntries.keyAt(i) / 2;
1274c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.wifiSystemStateEntries[i].wifiStateCount =
1275c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        mWifiSystemStateEntries.valueAt(i);
1276c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.wifiSystemStateEntries[i].isScreenOn =
1277c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        (mWifiSystemStateEntries.keyAt(i) % 2) > 0;
1278c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            }
1279107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne            mWifiLogProto.recordDurationSec = (int) ((mClock.getElapsedSinceBootMillis() / 1000)
1280107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne                    - mRecordStartTimeSec);
12817a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne
12827a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            /**
12837a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne             * Convert the SparseIntArray of RSSI poll rssi's and counts to the proto's repeated
12847a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne             * IntKeyVal array.
12857a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne             */
12867a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            for (int i = 0; i < mRssiPollCounts.size(); i++) {
12877a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                WifiMetricsProto.RssiPollCount keyVal = new WifiMetricsProto.RssiPollCount();
12887a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                keyVal.rssi = mRssiPollCounts.keyAt(i);
12897a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                keyVal.count = mRssiPollCounts.valueAt(i);
12907a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                rssis.add(keyVal);
12917a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            }
12927a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            mWifiLogProto.rssiPollRssiCount = rssis.toArray(mWifiLogProto.rssiPollRssiCount);
1293f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal
1294f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            /**
12955cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne             * Convert the SparseIntArray of RSSI delta rssi's and counts to the proto's repeated
12965cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne             * IntKeyVal array.
12975cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne             */
12985cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne            for (int i = 0; i < mRssiDeltaCounts.size(); i++) {
12995cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                WifiMetricsProto.RssiPollCount keyVal = new WifiMetricsProto.RssiPollCount();
13005cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                keyVal.rssi = mRssiDeltaCounts.keyAt(i);
13015cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                keyVal.count = mRssiDeltaCounts.valueAt(i);
13025cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne                rssiDeltas.add(keyVal);
13035cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne            }
13045cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne            mWifiLogProto.rssiPollDeltaCount = rssiDeltas.toArray(mWifiLogProto.rssiPollDeltaCount);
13055cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne
13065cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne            /**
1307f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal             * Convert the SparseIntArray of alert reasons and counts to the proto's repeated
1308f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal             * IntKeyVal array.
1309f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal             */
1310f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            for (int i = 0; i < mWifiAlertReasonCounts.size(); i++) {
1311f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                WifiMetricsProto.AlertReasonCount keyVal = new WifiMetricsProto.AlertReasonCount();
1312f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                keyVal.reason = mWifiAlertReasonCounts.keyAt(i);
1313f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                keyVal.count = mWifiAlertReasonCounts.valueAt(i);
1314f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                alertReasons.add(keyVal);
1315f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            }
1316f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            mWifiLogProto.alertReasonCount = alertReasons.toArray(mWifiLogProto.alertReasonCount);
13174569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao
13184569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao            /**
13194569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao            *  Convert the SparseIntArray of Wifi Score and counts to proto's repeated
13204569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao            * IntKeyVal array.
13214569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao            */
13224569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao            for (int score = 0; score < mWifiScoreCounts.size(); score++) {
13234569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao                WifiMetricsProto.WifiScoreCount keyVal = new WifiMetricsProto.WifiScoreCount();
13244569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao                keyVal.score = mWifiScoreCounts.keyAt(score);
13254569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao                keyVal.count = mWifiScoreCounts.valueAt(score);
13264569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao                scores.add(keyVal);
13274569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao            }
13284569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao            mWifiLogProto.wifiScoreCount = scores.toArray(mWifiLogProto.wifiScoreCount);
132944ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein
133044ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein            /**
133144ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein             * Convert the SparseIntArray of SoftAp Return codes and counts to proto's repeated
133244ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein             * IntKeyVal array.
133344ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein             */
133444ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein            int codeCounts = mSoftApManagerReturnCodeCounts.size();
133544ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein            mWifiLogProto.softApReturnCode = new WifiMetricsProto.SoftApReturnCodeCount[codeCounts];
133644ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein            for (int sapCode = 0; sapCode < codeCounts; sapCode++) {
133744ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                mWifiLogProto.softApReturnCode[sapCode] =
133844ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        new WifiMetricsProto.SoftApReturnCodeCount();
133944ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                mWifiLogProto.softApReturnCode[sapCode].startResult =
134044ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        mSoftApManagerReturnCodeCounts.keyAt(sapCode);
134144ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                mWifiLogProto.softApReturnCode[sapCode].count =
134244ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein                        mSoftApManagerReturnCodeCounts.valueAt(sapCode);
134344ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein            }
134446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
134546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            mWifiLogProto.staEventList = mStaEventList.toArray(mWifiLogProto.staEventList);
1346ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne        }
13471b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
13482532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne
13492532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    /**
13502532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne     * Clear all WifiMetrics, except for currentConnectionEvent.
13512532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne     */
13522532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    private void clear() {
13532532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        synchronized (mLock) {
13542532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mConnectionEventList.clear();
13552532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            if (mCurrentConnectionEvent != null) {
13562532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mConnectionEventList.add(mCurrentConnectionEvent);
13572532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            }
13582532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mScanReturnEntries.clear();
13592532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mWifiSystemStateEntries.clear();
1360107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne            mRecordStartTimeSec = mClock.getElapsedSinceBootMillis() / 1000;
13617a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            mRssiPollCounts.clear();
13625cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne            mRssiDeltaCounts.clear();
1363f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            mWifiAlertReasonCounts.clear();
13644569ebc2277f35b9bd1baa98194f963388e0c4caSohani Rao            mWifiScoreCounts.clear();
13652532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mWifiLogProto.clear();
13665cab82f2e70c360de79e6ca50da25c7657ed345dGlen Kuhne            mScanResultRssiTimestampMillis = -1;
136744ce135519e22d8c4746abac21c14111f1ce8667Rebecca Silberstein            mSoftApManagerReturnCodeCounts.clear();
136846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            mStaEventList.clear();
13692532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        }
13702532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    }
1371ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne
1372ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    /**
1373ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne     *  Set screen state (On/Off)
1374ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne     */
1375ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    public void setScreenState(boolean screenOn) {
1376ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        synchronized (mLock) {
1377ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mScreenOn = screenOn;
1378ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        }
1379ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    }
1380ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne
1381ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    /**
1382ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne     *  Set wifi state (WIFI_UNKNOWN, WIFI_DISABLED, WIFI_DISCONNECTED, WIFI_ASSOCIATED)
1383ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne     */
1384ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    public void setWifiState(int wifiState) {
1385ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        synchronized (mLock) {
1386ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mWifiState = wifiState;
1387ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        }
1388ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    }
138946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
139046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    /**
139146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * Message handler for interesting WifiMonitor messages. Generates StaEvents
139246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     */
139346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    private void processMessage(Message msg) {
139446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        StaEvent event = new StaEvent();
139546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        boolean logEvent = true;
139646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        switch (msg.what) {
139746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
139846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                event.type = StaEvent.TYPE_ASSOCIATION_REJECTION_EVENT;
139946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                event.associationTimedOut = msg.arg1 > 0 ? true : false;
140046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                event.status = msg.arg2;
140146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
140246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
140346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                event.type = StaEvent.TYPE_AUTHENTICATION_FAILURE_EVENT;
140446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                switch (msg.arg2) {
140546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                    case WifiManager.ERROR_AUTH_FAILURE_NONE:
140646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        event.authFailureReason = StaEvent.AUTH_FAILURE_NONE;
140746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        break;
140846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                    case WifiManager.ERROR_AUTH_FAILURE_TIMEOUT:
140946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        event.authFailureReason = StaEvent.AUTH_FAILURE_TIMEOUT;
141046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        break;
141146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                    case WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD:
141246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        event.authFailureReason = StaEvent.AUTH_FAILURE_WRONG_PSWD;
141346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        break;
141446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                    case WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE:
141546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        event.authFailureReason = StaEvent.AUTH_FAILURE_EAP_FAILURE;
141646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        break;
141746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                    default:
141846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        break;
141946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                }
142046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
142146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case WifiMonitor.NETWORK_CONNECTION_EVENT:
142246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                event.type = StaEvent.TYPE_NETWORK_CONNECTION_EVENT;
142346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
142446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
142546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                event.type = StaEvent.TYPE_NETWORK_DISCONNECTION_EVENT;
142646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                event.reason = msg.arg2;
142746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                event.localGen = msg.arg1 == 0 ? false : true;
142846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
142946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
143046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                logEvent = false;
143146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                StateChangeResult stateChangeResult = (StateChangeResult) msg.obj;
143246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                mSupplicantStateChangeBitmask |= supplicantStateToBit(stateChangeResult.state);
143346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
143446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case WifiStateMachine.CMD_ASSOCIATED_BSSID:
143546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                event.type = StaEvent.TYPE_CMD_ASSOCIATED_BSSID;
143646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
143746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case WifiStateMachine.CMD_TARGET_BSSID:
143846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                event.type = StaEvent.TYPE_CMD_TARGET_BSSID;
143946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
144046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            default:
144146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return;
144246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        }
144346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if (logEvent) {
144446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            addStaEvent(event);
144546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        }
144646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
144746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    /**
144846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * Log a StaEvent from WifiStateMachine. The StaEvent must not be one of the supplicant
144946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * generated event types, which are logged through 'sendMessage'
145046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * @param type StaEvent.EventType describing the event
145146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     */
145246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    public void logStaEvent(int type) {
145346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        logStaEvent(type, StaEvent.DISCONNECT_UNKNOWN, null);
145446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
145546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    /**
145646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * Log a StaEvent from WifiStateMachine. The StaEvent must not be one of the supplicant
145746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * generated event types, which are logged through 'sendMessage'
145846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * @param type StaEvent.EventType describing the event
145946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * @param config WifiConfiguration for a framework initiated connection attempt
146046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     */
146146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    public void logStaEvent(int type, WifiConfiguration config) {
146246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        logStaEvent(type, StaEvent.DISCONNECT_UNKNOWN, config);
146346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
146446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    /**
146546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * Log a StaEvent from WifiStateMachine. The StaEvent must not be one of the supplicant
146646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * generated event types, which are logged through 'sendMessage'
146746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * @param type StaEvent.EventType describing the event
146846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * @param frameworkDisconnectReason StaEvent.FrameworkDisconnectReason explaining why framework
146946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     *                                  initiated a FRAMEWORK_DISCONNECT
147046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     */
147146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    public void logStaEvent(int type, int frameworkDisconnectReason) {
147246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        logStaEvent(type, frameworkDisconnectReason, null);
147346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
147446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    /**
147546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * Log a StaEvent from WifiStateMachine. The StaEvent must not be one of the supplicant
147646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * generated event types, which are logged through 'sendMessage'
147746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * @param type StaEvent.EventType describing the event
147846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * @param frameworkDisconnectReason StaEvent.FrameworkDisconnectReason explaining why framework
147946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     *                                  initiated a FRAMEWORK_DISCONNECT
148046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * @param config WifiConfiguration for a framework initiated connection attempt
148146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     */
148246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    public void logStaEvent(int type, int frameworkDisconnectReason, WifiConfiguration config) {
148346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        switch (type) {
148446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL:
148546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_CMD_IP_CONFIGURATION_LOST:
148646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_CMD_IP_REACHABILITY_LOST:
148746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_CMD_START_CONNECT:
148846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_CMD_START_ROAM:
148946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_CONNECT_NETWORK:
149046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_NETWORK_AGENT_VALID_NETWORK:
149146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_FRAMEWORK_DISCONNECT:
149246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
149346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            default:
149446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                Log.e(TAG, "Unknown StaEvent:" + type);
149546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return;
149646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        }
149746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        StaEvent event = new StaEvent();
149846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        event.type = type;
149946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if (frameworkDisconnectReason != StaEvent.DISCONNECT_UNKNOWN) {
150046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            event.frameworkDisconnectReason = frameworkDisconnectReason;
150146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        }
150246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        event.configInfo = createConfigInfo(config);
150346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        addStaEvent(event);
150446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
150546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
150646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    private void addStaEvent(StaEvent staEvent) {
150746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        staEvent.startTimeMillis = mClock.getElapsedSinceBootMillis();
150846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        staEvent.lastRssi = mLastPollRssi;
150946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        staEvent.lastFreq = mLastPollFreq;
151046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        staEvent.lastLinkSpeed = mLastPollLinkSpeed;
151146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        staEvent.supplicantStateChangesBitmask = mSupplicantStateChangeBitmask;
151246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        mSupplicantStateChangeBitmask = 0;
151346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        mLastPollRssi = -127;
151446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        mLastPollFreq = -1;
151546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        mLastPollLinkSpeed = -1;
151646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        mStaEventList.add(staEvent);
151746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        // Prune StaEventList if it gets too long
151846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if (mStaEventList.size() > MAX_STA_EVENTS) mStaEventList.remove();
151946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
152046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
152146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    private ConfigInfo createConfigInfo(WifiConfiguration config) {
152246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if (config == null) return null;
152346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        ConfigInfo info = new ConfigInfo();
152446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        info.allowedKeyManagement = bitSetToInt(config.allowedKeyManagement);
152546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        info.allowedProtocols = bitSetToInt(config.allowedProtocols);
152646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        info.allowedAuthAlgorithms = bitSetToInt(config.allowedAuthAlgorithms);
152746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        info.allowedPairwiseCiphers = bitSetToInt(config.allowedPairwiseCiphers);
152846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        info.allowedGroupCiphers = bitSetToInt(config.allowedGroupCiphers);
152946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        info.hiddenSsid = config.hiddenSSID;
153046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        info.isPasspoint = config.isPasspoint();
153146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        info.isEphemeral = config.isEphemeral();
153246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        info.hasEverConnected = config.getNetworkSelectionStatus().getHasEverConnected();
153346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        ScanResult candidate = config.getNetworkSelectionStatus().getCandidate();
153446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if (candidate != null) {
153546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            info.scanRssi = candidate.level;
153646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            info.scanFreq = candidate.frequency;
153746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        }
153846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        return info;
153946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
154046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
154146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    public Handler getHandler() {
154246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        return mHandler;
154346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
154446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
154546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    // Rather than generate a StaEvent for each SUPPLICANT_STATE_CHANGE, cache these in a bitmask
154646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    // and attach it to the next event which is generated.
154746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    private int mSupplicantStateChangeBitmask = 0;
154846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
154946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    /**
155046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * Converts a SupplicantState value to a single bit, with position defined by
155146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * {@code StaEvent.SupplicantState}
155246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     */
155346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    public static int supplicantStateToBit(SupplicantState state) {
155446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        switch(state) {
155546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case DISCONNECTED:
155646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return 1 << StaEvent.STATE_DISCONNECTED;
155746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case INTERFACE_DISABLED:
155846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return 1 << StaEvent.STATE_INTERFACE_DISABLED;
155946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case INACTIVE:
156046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return 1 << StaEvent.STATE_INACTIVE;
156146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case SCANNING:
156246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return 1 << StaEvent.STATE_SCANNING;
156346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case AUTHENTICATING:
156446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return 1 << StaEvent.STATE_AUTHENTICATING;
156546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case ASSOCIATING:
156646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return 1 << StaEvent.STATE_ASSOCIATING;
156746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case ASSOCIATED:
156846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return 1 << StaEvent.STATE_ASSOCIATED;
156946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case FOUR_WAY_HANDSHAKE:
157046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return 1 << StaEvent.STATE_FOUR_WAY_HANDSHAKE;
157146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case GROUP_HANDSHAKE:
157246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return 1 << StaEvent.STATE_GROUP_HANDSHAKE;
157346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case COMPLETED:
157446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return 1 << StaEvent.STATE_COMPLETED;
157546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case DORMANT:
157646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return 1 << StaEvent.STATE_DORMANT;
157746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case UNINITIALIZED:
157846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return 1 << StaEvent.STATE_UNINITIALIZED;
157946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case INVALID:
158046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return 1 << StaEvent.STATE_INVALID;
158146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            default:
158246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                Log.wtf(TAG, "Got unknown supplicant state: " + state.ordinal());
158346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return 0;
158446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        }
158546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
158646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
158746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    private static String supplicantStateChangesBitmaskToString(int mask) {
158846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        StringBuilder sb = new StringBuilder();
158946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        sb.append("SUPPLICANT_STATE_CHANGE_EVENTS: {");
159046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if ((mask & (1 << StaEvent.STATE_DISCONNECTED)) > 0) sb.append(" DISCONNECTED");
159146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if ((mask & (1 << StaEvent.STATE_INTERFACE_DISABLED)) > 0) sb.append(" INTERFACE_DISABLED");
159246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if ((mask & (1 << StaEvent.STATE_INACTIVE)) > 0) sb.append(" INACTIVE");
159346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if ((mask & (1 << StaEvent.STATE_SCANNING)) > 0) sb.append(" SCANNING");
159446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if ((mask & (1 << StaEvent.STATE_AUTHENTICATING)) > 0) sb.append(" AUTHENTICATING");
159546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if ((mask & (1 << StaEvent.STATE_ASSOCIATING)) > 0) sb.append(" ASSOCIATING");
159646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if ((mask & (1 << StaEvent.STATE_ASSOCIATED)) > 0) sb.append(" ASSOCIATED");
159746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if ((mask & (1 << StaEvent.STATE_FOUR_WAY_HANDSHAKE)) > 0) sb.append(" FOUR_WAY_HANDSHAKE");
159846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if ((mask & (1 << StaEvent.STATE_GROUP_HANDSHAKE)) > 0) sb.append(" GROUP_HANDSHAKE");
159946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if ((mask & (1 << StaEvent.STATE_COMPLETED)) > 0) sb.append(" COMPLETED");
160046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if ((mask & (1 << StaEvent.STATE_DORMANT)) > 0) sb.append(" DORMANT");
160146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if ((mask & (1 << StaEvent.STATE_UNINITIALIZED)) > 0) sb.append(" UNINITIALIZED");
160246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if ((mask & (1 << StaEvent.STATE_INVALID)) > 0) sb.append(" INVALID");
160346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        sb.append("}");
160446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        return sb.toString();
160546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
160646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
160746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    /**
160846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * Returns a human readable string from a Sta Event. Only adds information relevant to the event
160946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * type.
161046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     */
161146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    public static String staEventToString(StaEvent event) {
161246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if (event == null) return "<NULL>";
161346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        StringBuilder sb = new StringBuilder();
161446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        Long time = event.startTimeMillis;
161546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        sb.append(String.format("%9d ", time.longValue())).append(" ");
161646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        switch (event.type) {
161746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_ASSOCIATION_REJECTION_EVENT:
161846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("ASSOCIATION_REJECTION_EVENT:")
161946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        .append(" timedOut=").append(event.associationTimedOut)
162046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        .append(" status=").append(event.status).append(":")
162146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        .append(ISupplicantStaIfaceCallback.StatusCode.toString(event.status));
162246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
162346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_AUTHENTICATION_FAILURE_EVENT:
162446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("AUTHENTICATION_FAILURE_EVENT: reason=").append(event.authFailureReason)
162546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        .append(":").append(authFailureReasonToString(event.authFailureReason));
162646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
162746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_NETWORK_CONNECTION_EVENT:
162846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("NETWORK_CONNECTION_EVENT:");
162946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
163046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_NETWORK_DISCONNECTION_EVENT:
163146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("NETWORK_DISCONNECTION_EVENT:")
163246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        .append(" local_gen=").append(event.localGen)
163346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        .append(" reason=").append(event.reason).append(":")
163446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        .append(ISupplicantStaIfaceCallback.ReasonCode.toString(
163546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                                (event.reason >= 0 ? event.reason : -1 * event.reason)));
163646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
163746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_CMD_ASSOCIATED_BSSID:
163846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("CMD_ASSOCIATED_BSSID:");
163946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
164046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL:
164146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("CMD_IP_CONFIGURATION_SUCCESSFUL:");
164246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
164346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_CMD_IP_CONFIGURATION_LOST:
164446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("CMD_IP_CONFIGURATION_LOST:");
164546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
164646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_CMD_IP_REACHABILITY_LOST:
164746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("CMD_IP_REACHABILITY_LOST:");
164846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
164946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_CMD_TARGET_BSSID:
165046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("CMD_TARGET_BSSID:");
165146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
165246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_CMD_START_CONNECT:
165346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("CMD_START_CONNECT:");
165446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
165546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_CMD_START_ROAM:
165646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("CMD_START_ROAM:");
165746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
165846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_CONNECT_NETWORK:
165946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("CONNECT_NETWORK:");
166046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
166146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_NETWORK_AGENT_VALID_NETWORK:
166246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("NETWORK_AGENT_VALID_NETWORK:");
166346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
166446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.TYPE_FRAMEWORK_DISCONNECT:
166546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("FRAMEWORK_DISCONNECT:")
166646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        .append(" reason=")
166746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                        .append(frameworkDisconnectReasonToString(event.frameworkDisconnectReason));
166846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
166946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            default:
167046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                sb.append("UNKNOWN " + event.type + ":");
167146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                break;
167246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        }
167346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if (event.lastRssi != -127) sb.append(" lastRssi=").append(event.lastRssi);
167446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if (event.lastFreq != -1) sb.append(" lastFreq=").append(event.lastFreq);
167546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if (event.lastLinkSpeed != -1) sb.append(" lastLinkSpeed=").append(event.lastLinkSpeed);
167646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if (event.supplicantStateChangesBitmask != 0) {
167746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            sb.append("\n             ").append(supplicantStateChangesBitmaskToString(
167846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                    event.supplicantStateChangesBitmask));
167946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        }
168046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        if (event.configInfo != null) {
168146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            sb.append("\n             ").append(configInfoToString(event.configInfo));
168246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        }
168346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
168446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        return sb.toString();
168546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
168646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
168746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    private static String authFailureReasonToString(int authFailureReason) {
168846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        switch (authFailureReason) {
168946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.AUTH_FAILURE_NONE:
169046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return "ERROR_AUTH_FAILURE_NONE";
169146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.AUTH_FAILURE_TIMEOUT:
169246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return "ERROR_AUTH_FAILURE_TIMEOUT";
169346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.AUTH_FAILURE_WRONG_PSWD:
169446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return "ERROR_AUTH_FAILURE_WRONG_PSWD";
169546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.AUTH_FAILURE_EAP_FAILURE:
169646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return "ERROR_AUTH_FAILURE_EAP_FAILURE";
169746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            default:
169846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return "";
169946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        }
170046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
170146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
170246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    private static String frameworkDisconnectReasonToString(int frameworkDisconnectReason) {
170346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        switch (frameworkDisconnectReason) {
170446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.DISCONNECT_API:
170546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return "DISCONNECT_API";
170646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.DISCONNECT_GENERIC:
170746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return "DISCONNECT_GENERIC";
170846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.DISCONNECT_UNWANTED:
170946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return "DISCONNECT_UNWANTED";
171046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.DISCONNECT_ROAM_WATCHDOG_TIMER:
171146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return "DISCONNECT_ROAM_WATCHDOG_TIMER";
171246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.DISCONNECT_P2P_DISCONNECT_WIFI_REQUEST:
171346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return "DISCONNECT_P2P_DISCONNECT_WIFI_REQUEST";
171446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            case StaEvent.DISCONNECT_RESET_SIM_NETWORKS:
171546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return "DISCONNECT_RESET_SIM_NETWORKS";
171646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            default:
171746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                return "DISCONNECT_UNKNOWN=" + frameworkDisconnectReason;
171846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        }
171946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
172046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
172146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    private static String configInfoToString(ConfigInfo info) {
172246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        StringBuilder sb = new StringBuilder();
172346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        sb.append("ConfigInfo:")
172446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                .append(" allowed_key_management=").append(info.allowedKeyManagement)
172546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                .append(" allowed_protocols=").append(info.allowedProtocols)
172646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                .append(" allowed_auth_algorithms=").append(info.allowedAuthAlgorithms)
172746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                .append(" allowed_pairwise_ciphers=").append(info.allowedPairwiseCiphers)
172846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                .append(" allowed_group_ciphers=").append(info.allowedGroupCiphers)
172946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                .append(" hidden_ssid=").append(info.hiddenSsid)
173046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                .append(" is_passpoint=").append(info.isPasspoint)
173146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                .append(" is_ephemeral=").append(info.isEphemeral)
173246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                .append(" has_ever_connected=").append(info.hasEverConnected)
173346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                .append(" scan_rssi=").append(info.scanRssi)
173446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne                .append(" scan_freq=").append(info.scanFreq);
173546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        return sb.toString();
173646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
173746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
173846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    public static final int MAX_STA_EVENTS = 512;
173946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    private LinkedList<StaEvent> mStaEventList = new LinkedList<StaEvent>();
174046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    private int mLastPollRssi = -127;
174146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    private int mLastPollLinkSpeed = -1;
174246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    private int mLastPollFreq = -1;
174346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne
174446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    /**
174546c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     * Converts the first 31 bits of a BitSet to a little endian int
174646c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne     */
174746c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    private static int bitSetToInt(BitSet bits) {
174846c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        int value = 0;
174946c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        int nBits = bits.length() < 31 ? bits.length() : 31;
175046c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        for (int i = 0; i < nBits; i++) {
175146c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne            value += bits.get(i) ? (1 << i) : 0;
175246c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        }
175346c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne        return value;
175446c84f9fd984cc4b67f5252e30bce7f756be558cGlen Kuhne    }
17551b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne}
1756