WifiMetrics.java revision f11073c03746f1c79e6a316884bc59574b562a8b
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
194dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhneimport android.net.wifi.ScanResult;
202532a24b254d724a9b6771d327dc410b32b18602Glen Kuhneimport android.net.wifi.WifiConfiguration;
211b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport android.util.Base64;
22c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhneimport android.util.Log;
23c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhneimport android.util.SparseIntArray;
241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
25f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhneimport com.android.server.wifi.hotspot2.NetworkDetail;
26f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhneimport com.android.server.wifi.util.InformationElementUtil;
27f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne
281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.io.FileDescriptor;
291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.io.PrintWriter;
301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.util.ArrayList;
311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.util.Calendar;
321b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.util.List;
331b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
341b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne/**
351b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Provides storage for wireless connectivity metrics, as they are generated.
361b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Metrics logged by this class include:
371b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne *   Aggregated connection stats (num of connections, num of failures, ...)
381b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne *   Discrete connection event stats (time, duration, failure codes, ...)
391b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne *   Router details (technology type, authentication type, ...)
401b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne *   Scan stats
411b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */
421b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhnepublic class WifiMetrics {
431b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    private static final String TAG = "WifiMetrics";
44c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private static final boolean DBG = false;
457a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    /**
467a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne     * Clamp the RSSI poll counts to values between [MIN,MAX]_RSSI_POLL
477a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne     */
487a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    private static final int MAX_RSSI_POLL = 0;
497a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    private static final int MIN_RSSI_POLL = -127;
501b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    private final Object mLock = new Object();
512532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    private static final int MAX_CONNECTION_EVENTS = 256;
52107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne    private Clock mClock;
53ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    private boolean mScreenOn;
54ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    private int mWifiState;
551b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
561b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Metrics are stored within an instance of the WifiLog proto during runtime,
571b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * The ConnectionEvent, SystemStateEntries & ScanReturnEntries metrics are stored during
581b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * runtime in member lists of this WifiMetrics class, with the final WifiLog proto being pieced
591b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * together at dump-time
601b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
617a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    private final WifiMetricsProto.WifiLog mWifiLogProto = new WifiMetricsProto.WifiLog();
621b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
631b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Session information that gets logged for every Wifi connection attempt.
641b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
657a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    private final List<ConnectionEvent> mConnectionEventList = new ArrayList<>();
661b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
671b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * The latest started (but un-ended) connection attempt
681b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
691b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    private ConnectionEvent mCurrentConnectionEvent;
701b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
711b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Count of number of times each scan return code, indexed by WifiLog.ScanReturnCode
721b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
737a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    private final SparseIntArray mScanReturnEntries = new SparseIntArray();
741b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
751b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Mapping of system state to the counts of scans requested in that wifi state * screenOn
761b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * combination. Indexed by WifiLog.WifiState * (1 + screenOn)
771b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
787a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    private final SparseIntArray mWifiSystemStateEntries = new SparseIntArray();
79f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal    /** Mapping of RSSI values to counts. */
80f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal    private final SparseIntArray mRssiPollCounts = new SparseIntArray();
81f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal    /** Mapping of alert reason to the respective alert count. */
82f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal    private final SparseIntArray mWifiAlertReasonCounts = new SparseIntArray();
83107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne    /**
84107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne     * Records the getElapsedSinceBootMillis (in seconds) that represents the beginning of data
85107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne     * capture for for this WifiMetricsProto
86107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne     */
87107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne    private long mRecordStartTimeSec;
881b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
891b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    class RouterFingerPrint {
901b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        private WifiMetricsProto.RouterFingerPrint mRouterFingerPrintProto;
912532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        RouterFingerPrint() {
921b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mRouterFingerPrintProto = new WifiMetricsProto.RouterFingerPrint();
931b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
941b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
951b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        public String toString() {
961b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            StringBuilder sb = new StringBuilder();
971b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            synchronized (mLock) {
981b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append("mConnectionEvent.roamType=" + mRouterFingerPrintProto.roamType);
991b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mChannelInfo=" + mRouterFingerPrintProto.channelInfo);
1001b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mDtim=" + mRouterFingerPrintProto.dtim);
1011b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mAuthentication=" + mRouterFingerPrintProto.authentication);
1021b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mHidden=" + mRouterFingerPrintProto.hidden);
1031b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mRouterTechnology=" + mRouterFingerPrintProto.routerTechnology);
1041b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mSupportsIpv6=" + mRouterFingerPrintProto.supportsIpv6);
1051b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
1061b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            return sb.toString();
1071b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
1082532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        public void updateFromWifiConfiguration(WifiConfiguration config) {
109ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne            synchronized (mLock) {
110ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                if (config != null) {
111ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // Is this a hidden network
112ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    mRouterFingerPrintProto.hidden = config.hiddenSSID;
113ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // Config may not have a valid dtimInterval set yet, in which case dtim will be zero
114ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // (These are only populated from beacon frame scan results, which are returned as
115ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // scan results from the chip far less frequently than Probe-responses)
116ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    if (config.dtimInterval > 0) {
117ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        mRouterFingerPrintProto.dtim = config.dtimInterval;
118ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    }
119ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    mCurrentConnectionEvent.mConfigSsid = config.SSID;
120ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // Get AuthType information from config (We do this again from ScanResult after
121ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // associating with BSSID)
122ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    if (config.allowedKeyManagement != null
123ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                            && config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) {
124ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
125ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                                .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_OPEN;
126ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    } else if (config.isEnterprise()) {
127ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
128ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                                .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE;
129ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    } else {
130ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
131ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                                .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL;
132ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    }
133ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // If there's a ScanResult candidate associated with this config already, get it and
134ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // log (more accurate) metrics from it
135ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    ScanResult candidate = config.getNetworkSelectionStatus().getCandidate();
136ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    if (candidate != null) {
137ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        updateMetricsFromScanResult(candidate);
138ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    }
13996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                }
1402532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            }
1412532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        }
1421b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
1431b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
1441b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
1451b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Log event, tracking the start time, end time and result of a wireless connection attempt.
1461b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
1471b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    class ConnectionEvent {
1481b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        WifiMetricsProto.ConnectionEvent mConnectionEvent;
14996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        //<TODO> Move these constants into a wifi.proto Enum, and create a new Failure Type field
15096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        //covering more than just l2 failures. see b/27652362
15196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        /**
15296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne         * Failure codes, used for the 'level_2_failure_code' Connection event field (covers a lot
15396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne         * more failures than just l2 though, since the proto does not have a place to log
15496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne         * framework failures)
15596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne         */
1562532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // Failure is unknown
15796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_UNKNOWN = 0;
1582532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // NONE
15996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_NONE = 1;
1602532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // ASSOCIATION_REJECTION_EVENT
16196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_ASSOCIATION_REJECTION = 2;
1622532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // AUTHENTICATION_FAILURE_EVENT
16396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_AUTHENTICATION_FAILURE = 3;
1642532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // SSID_TEMP_DISABLED (Also Auth failure)
16596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_SSID_TEMP_DISABLED = 4;
1664dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        // reconnect() or reassociate() call to WifiNative failed
16796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_CONNECT_NETWORK_FAILED = 5;
1682532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // NETWORK_DISCONNECTION_EVENT
16996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_NETWORK_DISCONNECTION = 6;
1704dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        // NEW_CONNECTION_ATTEMPT before previous finished
17196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_NEW_CONNECTION_ATTEMPT = 7;
17296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        // New connection attempt to the same network & bssid
17396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_REDUNDANT_CONNECTION_ATTEMPT = 8;
17496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        // Roam Watchdog timer triggered (Roaming timed out)
17596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_ROAM_TIMEOUT = 9;
17696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        // DHCP failure
17796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_DHCP = 10;
17896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne
1794dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        RouterFingerPrint mRouterFingerPrint;
1804dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        private long mRealStartTime;
1814dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        private long mRealEndTime;
1824dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        private String mConfigSsid;
1834dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        private String mConfigBssid;
184ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        private int mWifiState;
185ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        private boolean mScreenOn;
1862532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne
1871b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        private ConnectionEvent() {
1881b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mConnectionEvent = new WifiMetricsProto.ConnectionEvent();
189947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne            mRealEndTime = 0;
190947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne            mRealStartTime = 0;
1912532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mRouterFingerPrint = new RouterFingerPrint();
1922532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mConnectionEvent.routerFingerprint = mRouterFingerPrint.mRouterFingerPrintProto;
1934dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mConfigSsid = "<NULL>";
1944dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mConfigBssid = "<NULL>";
195ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mWifiState = WifiMetricsProto.WifiLog.WIFI_UNKNOWN;
196ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mScreenOn = false;
1971b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
1981b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
1991b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        public String toString() {
2001b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            StringBuilder sb = new StringBuilder();
2011b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            sb.append("startTime=");
2021b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            Calendar c = Calendar.getInstance();
2031b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            synchronized (mLock) {
2041b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                c.setTimeInMillis(mConnectionEvent.startTimeMillis);
2051b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(mConnectionEvent.startTimeMillis == 0 ? "            <null>" :
2061b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c));
2074dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", SSID=");
2084dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(mConfigSsid);
2094dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", BSSID=");
2104dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(mConfigBssid);
2114dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", durationMillis=");
2121b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(mConnectionEvent.durationTakenToConnectMillis);
2132532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                sb.append(", roamType=");
2144dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                switch(mConnectionEvent.roamType) {
2152532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 1:
2162532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_NONE");
2172532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2182532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 2:
2192532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_DBDC");
2202532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2212532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 3:
2222532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_ENTERPRISE");
2232532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2242532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 4:
2252532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_USER_SELECTED");
2262532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2272532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 5:
2282532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_UNRELATED");
2292532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2302532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    default:
2312532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_UNKNOWN");
2322532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                }
2334dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", connectionResult=");
2344dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(mConnectionEvent.connectionResult);
2351b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", level2FailureCode=");
2364dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                switch(mConnectionEvent.level2FailureCode) {
23796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_NONE:
2384dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NONE");
2394dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
24096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_ASSOCIATION_REJECTION:
2414dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("ASSOCIATION_REJECTION");
2424dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
24396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_AUTHENTICATION_FAILURE:
2444dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("AUTHENTICATION_FAILURE");
2454dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
24696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_SSID_TEMP_DISABLED:
2474dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("SSID_TEMP_DISABLED");
2484dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
24996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_CONNECT_NETWORK_FAILED:
2504dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("CONNECT_NETWORK_FAILED");
2514dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
25296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_NETWORK_DISCONNECTION:
2534dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NETWORK_DISCONNECTION");
2544dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
25596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_NEW_CONNECTION_ATTEMPT:
2564dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NEW_CONNECTION_ATTEMPT");
2574dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
25896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_REDUNDANT_CONNECTION_ATTEMPT:
25996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        sb.append("REDUNDANT_CONNECTION_ATTEMPT");
26096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        break;
26196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_ROAM_TIMEOUT:
26296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        sb.append("ROAM_TIMEOUT");
26396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        break;
26496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_DHCP:
26596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        sb.append("DHCP");
2664dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    default:
2674dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("UNKNOWN");
2684dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
2694dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                }
2701b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", connectivityLevelFailureCode=");
2714dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                switch(mConnectionEvent.connectivityLevelFailureCode) {
2724dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    case WifiMetricsProto.ConnectionEvent.HLF_NONE:
2734dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NONE");
2744dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
2754dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    case WifiMetricsProto.ConnectionEvent.HLF_DHCP:
2764dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("DHCP");
2774dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
2784dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    case WifiMetricsProto.ConnectionEvent.HLF_NO_INTERNET:
2794dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NO_INTERNET");
2804dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
2814dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    case WifiMetricsProto.ConnectionEvent.HLF_UNWANTED:
2824dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("UNWANTED");
2834dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
2844dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    default:
2854dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("UNKNOWN");
2864dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
2874dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                }
2884dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", signalStrength=");
2894dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(mConnectionEvent.signalStrength);
290ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                sb.append(", wifiState=");
291ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                switch(mWifiState) {
292ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                    case WifiMetricsProto.WifiLog.WIFI_DISABLED:
293ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        sb.append("WIFI_DISABLED");
294ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        break;
295ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                    case WifiMetricsProto.WifiLog.WIFI_DISCONNECTED:
296ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        sb.append("WIFI_DISCONNECTED");
297ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        break;
298ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                    case WifiMetricsProto.WifiLog.WIFI_ASSOCIATED:
299ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        sb.append("WIFI_ASSOCIATED");
300ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        break;
301ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                    default:
302ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        sb.append("WIFI_UNKNOWN");
303ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        break;
304ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                }
305ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                sb.append(", screenOn=");
306ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                sb.append(mScreenOn);
307ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                sb.append(". mRouterFingerprint: ");
3081b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(mRouterFingerPrint.toString());
3091b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
3101b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            return sb.toString();
3111b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
3121b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
3131b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
314107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne    public WifiMetrics(Clock clock) {
315107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne        mClock = clock;
3161b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        mCurrentConnectionEvent = null;
317ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        mScreenOn = true;
318ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        mWifiState = WifiMetricsProto.WifiLog.WIFI_DISABLED;
319107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne        mRecordStartTimeSec = mClock.getElapsedSinceBootMillis() / 1000;
3201b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
3211b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
322c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    // Values used for indexing SystemStateEntries
323c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private static final int SCREEN_ON = 1;
324c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private static final int SCREEN_OFF = 0;
325c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
3261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
3271b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Create a new connection event. Call when wifi attempts to make a new network connection
3281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * If there is a current 'un-ended' connection event, it will be ended with UNKNOWN connectivity
3291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * failure code.
3301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Gathers and sets the RouterFingerPrint data as well
3311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
332947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne     * @param config WifiConfiguration of the config used for the current connection attempt
3331b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param roamType Roam type that caused connection attempt, see WifiMetricsProto.WifiLog.ROAM_X
3341b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
33596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne    public void startConnectionEvent(WifiConfiguration config, String targetBSSID, int roamType) {
3361b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
33796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            // Check if this is overlapping another current connection event
33896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            if (mCurrentConnectionEvent != null) {
33996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                //Is this new Connection Event the same as the current one
34096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                if (mCurrentConnectionEvent.mConfigSsid != null
34196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        && mCurrentConnectionEvent.mConfigBssid != null
34296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        && config != null
34396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        && mCurrentConnectionEvent.mConfigSsid.equals(config.SSID)
34496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        && (mCurrentConnectionEvent.mConfigBssid.equals("any")
34596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        || mCurrentConnectionEvent.mConfigBssid.equals(targetBSSID))) {
34696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    mCurrentConnectionEvent.mConfigBssid = targetBSSID;
34796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    // End Connection Event due to new connection attempt to the same network
34896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    endConnectionEvent(ConnectionEvent.FAILURE_REDUNDANT_CONNECTION_ATTEMPT,
34996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                            WifiMetricsProto.ConnectionEvent.HLF_NONE);
35096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                } else {
35196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    // End Connection Event due to new connection attempt to different network
35296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    endConnectionEvent(ConnectionEvent.FAILURE_NEW_CONNECTION_ATTEMPT,
35396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                            WifiMetricsProto.ConnectionEvent.HLF_NONE);
35496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                }
35596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            }
35696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            //If past maximum connection events, start removing the oldest
3574dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            while(mConnectionEventList.size() >= MAX_CONNECTION_EVENTS) {
3584dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                mConnectionEventList.remove(0);
3594dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            }
3604dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mCurrentConnectionEvent = new ConnectionEvent();
3614dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mCurrentConnectionEvent.mConnectionEvent.startTimeMillis =
362107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne                    mClock.getWallClockMillis();
36396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            mCurrentConnectionEvent.mConfigBssid = targetBSSID;
3644dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mCurrentConnectionEvent.mConnectionEvent.roamType = roamType;
3654dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mCurrentConnectionEvent.mRouterFingerPrint.updateFromWifiConfiguration(config);
36696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            mCurrentConnectionEvent.mConfigBssid = "any";
367107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne            mCurrentConnectionEvent.mRealStartTime = mClock.getElapsedSinceBootMillis();
368ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mCurrentConnectionEvent.mWifiState = mWifiState;
369ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mCurrentConnectionEvent.mScreenOn = mScreenOn;
3704dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mConnectionEventList.add(mCurrentConnectionEvent);
3711b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
3721b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
3731b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
3741b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
3752532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne     * set the RoamType of the current ConnectionEvent (if any)
3762532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne     */
3772532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    public void setConnectionEventRoamType(int roamType) {
378ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne        synchronized (mLock) {
379ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne            if (mCurrentConnectionEvent != null) {
380ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.roamType = roamType;
381ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne            }
3822532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        }
3832532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    }
384f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne
385f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne    /**
386f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne     * Set AP related metrics from ScanDetail
387f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne     */
388f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne    public void setConnectionScanDetail(ScanDetail scanDetail) {
389ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne        synchronized (mLock) {
390ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne            if (mCurrentConnectionEvent != null && scanDetail != null) {
391ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                NetworkDetail networkDetail = scanDetail.getNetworkDetail();
392ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                ScanResult scanResult = scanDetail.getScanResult();
393ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                //Ensure that we have a networkDetail, and that it corresponds to the currently
394ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                //tracked connection attempt
395ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                if (networkDetail != null && scanResult != null
396ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        && mCurrentConnectionEvent.mConfigSsid != null
397ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        && mCurrentConnectionEvent.mConfigSsid
398ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        .equals("\"" + networkDetail.getSSID() + "\"")) {
399ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    updateMetricsFromNetworkDetail(networkDetail);
400ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    updateMetricsFromScanResult(scanResult);
401ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                }
402f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne            }
403f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne        }
404f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne    }
405f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne
4062532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    /**
4071b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * End a Connection event record. Call when wifi connection attempt succeeds or fails.
4081b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * If a Connection event has not been started and is active when .end is called, a new one is
4091b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * created with zero duration.
4101b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
4111b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param level2FailureCode Level 2 failure code returned by supplicant
4121b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param connectivityFailureCode WifiMetricsProto.ConnectionEvent.HLF_X
4131b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
4141b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void endConnectionEvent(int level2FailureCode, int connectivityFailureCode) {
4151b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
4162532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            if (mCurrentConnectionEvent != null) {
4172532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                boolean result = (level2FailureCode == 1)
4182532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        && (connectivityFailureCode == WifiMetricsProto.ConnectionEvent.HLF_NONE);
4192532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.connectionResult = result ? 1 : 0;
420107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne                mCurrentConnectionEvent.mRealEndTime = mClock.getElapsedSinceBootMillis();
4212532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.durationTakenToConnectMillis = (int)
4222532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        (mCurrentConnectionEvent.mRealEndTime
4232532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        - mCurrentConnectionEvent.mRealStartTime);
4242532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.level2FailureCode = level2FailureCode;
4252532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.connectivityLevelFailureCode =
4262532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        connectivityFailureCode;
427f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne                // ConnectionEvent already added to ConnectionEvents List. Safe to null current here
4282532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent = null;
4291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
4301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
4311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
4321b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
4332b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    /**
4342b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne     * Set ConnectionEvent DTIM Interval (if set), and 802.11 Connection mode, from NetworkDetail
4352b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne     */
4362b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    private void updateMetricsFromNetworkDetail(NetworkDetail networkDetail) {
4372b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        int dtimInterval = networkDetail.getDtimInterval();
4382b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        if (dtimInterval > 0) {
4392b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.dtim =
4402b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                    dtimInterval;
4412b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        }
4422b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        int connectionWifiMode;
4432b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        switch (networkDetail.getWifiMode()) {
4442b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_UNDEFINED:
4452b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_UNKNOWN;
4462b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
4472b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11A:
4482b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_A;
4492b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
4502b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11B:
4512b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_B;
4522b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
4532b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11G:
4542b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_G;
4552b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
4562b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11N:
4572b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_N;
4582b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
4592b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11AC  :
4602b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_AC;
4612b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
4622b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            default:
4632b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_OTHER;
4642b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
4652b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        }
4662b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
4672b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                .routerTechnology = connectionWifiMode;
4682b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    }
4692b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne
4702b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    /**
4712b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne     * Set ConnectionEvent RSSI and authentication type from ScanResult
4722b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne     */
4732b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    private void updateMetricsFromScanResult(ScanResult scanResult) {
4742b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        mCurrentConnectionEvent.mConnectionEvent.signalStrength = scanResult.level;
4752b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication =
4762b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                WifiMetricsProto.RouterFingerPrint.AUTH_OPEN;
47796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        mCurrentConnectionEvent.mConfigBssid = scanResult.BSSID;
4782b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        if (scanResult.capabilities != null) {
4792b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            if (scanResult.capabilities.contains("WEP")) {
4802b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication =
4812b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                        WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL;
4822b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            } else if (scanResult.capabilities.contains("PSK")) {
4832b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication =
4842b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                        WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL;
4852b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            } else if (scanResult.capabilities.contains("EAP")) {
4862b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication =
4872b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                        WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE;
4882b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            }
4892b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        }
49096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.channelInfo =
49196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                scanResult.frequency;
4922b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    }
4932b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne
4941b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setNumSavedNetworks(int num) {
4951b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
4961b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numSavedNetworks = num;
4971b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
4981b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
4991b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5001b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setNumOpenNetworks(int num) {
5011b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5021b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numOpenNetworks = num;
5031b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5041b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5051b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5061b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setNumPersonalNetworks(int num) {
5071b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5081b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numPersonalNetworks = num;
5091b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5101b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5111b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5121b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setNumEnterpriseNetworks(int num) {
5131b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5141b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numEnterpriseNetworks = num;
5151b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5161b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5171b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5181b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setNumNetworksAddedByUser(int num) {
5191b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5201b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numNetworksAddedByUser = num;
5211b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5221b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5231b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setNumNetworksAddedByApps(int num) {
5251b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numNetworksAddedByApps = num;
5271b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setIsLocationEnabled(boolean enabled) {
5311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5321b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.isLocationEnabled = enabled;
5331b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5341b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5351b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5361b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setIsScanningAlwaysEnabled(boolean enabled) {
5371b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5381b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.isScanningAlwaysEnabled = enabled;
5391b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5401b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5411b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5421b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
5431b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Increment Non Empty Scan Results count
5441b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
5451b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void incrementNonEmptyScanResultCount() {
546c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        if (DBG) Log.v(TAG, "incrementNonEmptyScanResultCount");
5471b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5481b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numNonEmptyScanResults++;
5491b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5501b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5511b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5521b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
5531b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Increment Empty Scan Results count
5541b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
5551b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void incrementEmptyScanResultCount() {
556c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        if (DBG) Log.v(TAG, "incrementEmptyScanResultCount");
5571b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5581b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numEmptyScanResults++;
5591b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5601b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5611b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5621b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
563c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Increment background scan count
564c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
565c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public void incrementBackgroundScanCount() {
566c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        if (DBG) Log.v(TAG, "incrementBackgroundScanCount");
567c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
568c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiLogProto.numBackgroundScans++;
569c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
570c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
571c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
572c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne   /**
573c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Get Background scan count
574c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
575c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public int getBackgroundScanCount() {
576c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
577c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            return mWifiLogProto.numBackgroundScans;
578c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
579c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
580c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
581c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
58270ce5a4cbaf5aaccd4e542e7bb87196fb4464a6eGlen Kuhne     * Increment oneshot scan count, and the associated WifiSystemScanStateCount entry
583c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
584c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public void incrementOneshotScanCount() {
585c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
586c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiLogProto.numOneshotScans++;
587c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
58870ce5a4cbaf5aaccd4e542e7bb87196fb4464a6eGlen Kuhne        incrementWifiSystemScanStateCount(mWifiState, mScreenOn);
589c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
590c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
591c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
592c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Get oneshot scan count
593c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
594c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public int getOneshotScanCount() {
595c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
596c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            return mWifiLogProto.numOneshotScans;
597c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
598c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
599c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
600c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private String returnCodeToString(int scanReturnCode) {
601c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        switch(scanReturnCode){
602c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.SCAN_UNKNOWN:
603c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "SCAN_UNKNOWN";
604c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.SCAN_SUCCESS:
605c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "SCAN_SUCCESS";
606c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED:
607c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "SCAN_FAILURE_INTERRUPTED";
608c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION:
609c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "SCAN_FAILURE_INVALID_CONFIGURATION";
610c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.FAILURE_WIFI_DISABLED:
611c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "FAILURE_WIFI_DISABLED";
612c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            default:
613c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "<UNKNOWN>";
614c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
615c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
616c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
617c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
6181b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Increment count of scan return code occurrence
6191b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
6201b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param scanReturnCode Return code from scan attempt WifiMetricsProto.WifiLog.SCAN_X
6211b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
622c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public void incrementScanReturnEntry(int scanReturnCode, int countToAdd) {
6231b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
624c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            if (DBG) Log.v(TAG, "incrementScanReturnEntry " + returnCodeToString(scanReturnCode));
625c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            int entry = mScanReturnEntries.get(scanReturnCode);
626c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            entry += countToAdd;
6271b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mScanReturnEntries.put(scanReturnCode, entry);
6281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
6291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
630c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
631c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Get the count of this scanReturnCode
632c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * @param scanReturnCode that we are getting the count for
633c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
634c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public int getScanReturnEntry(int scanReturnCode) {
635c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
636c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            return mScanReturnEntries.get(scanReturnCode);
637c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
638c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
639c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
640c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private String wifiSystemStateToString(int state) {
641c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        switch(state){
642c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.WIFI_UNKNOWN:
643c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "WIFI_UNKNOWN";
644c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.WIFI_DISABLED:
645c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "WIFI_DISABLED";
646c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.WIFI_DISCONNECTED:
647c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "WIFI_DISCONNECTED";
648c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.WIFI_ASSOCIATED:
649c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "WIFI_ASSOCIATED";
650c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            default:
651c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "default";
652c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
653c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
6541b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
6551b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
6561b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Increments the count of scans initiated by each wifi state, accounts for screenOn/Off
6571b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
6581b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param state State of the system when scan was initiated, see WifiMetricsProto.WifiLog.WIFI_X
6591b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param screenOn Is the screen on
6601b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
6611b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void incrementWifiSystemScanStateCount(int state, boolean screenOn) {
6621b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
663c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            if (DBG) {
664c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                Log.v(TAG, "incrementWifiSystemScanStateCount " + wifiSystemStateToString(state)
665c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + " " + screenOn);
6661b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
667c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            int index = (state * 2) + (screenOn ? SCREEN_ON : SCREEN_OFF);
668c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            int entry = mWifiSystemStateEntries.get(index);
669c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            entry++;
670c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiSystemStateEntries.put(index, entry);
671c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
672c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
673c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
674c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
675c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Get the count of this system State Entry
676c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
677c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public int getSystemStateCount(int state, boolean screenOn) {
678c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
679c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            int index = state * 2 + (screenOn ? SCREEN_ON : SCREEN_OFF);
680c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            return mWifiSystemStateEntries.get(index);
6811b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
6821b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
6831b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
684ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    /**
6855f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment number of times the Watchdog of Last Resort triggered, resetting the wifi stack
6865f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
6875f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggers() {
6885f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
6895f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggers++;
6905f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
6915f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
6925f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
6935f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks over bad association threshold when watchdog triggered
6945f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
6955f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogBadAssociationNetworksTotal(int count) {
6965f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
6975f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal += count;
6985f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
6995f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7005f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7015f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks over bad authentication threshold when watchdog triggered
7025f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7035f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogBadAuthenticationNetworksTotal(int count) {
7045f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7055f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal += count;
7065f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7075f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7085f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7095f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks over bad dhcp threshold when watchdog triggered
7105f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7115f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogBadDhcpNetworksTotal(int count) {
7125f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7135f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal += count;
7145f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7155f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7165f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7175f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks over bad other threshold when watchdog triggered
7185f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7195f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogBadOtherNetworksTotal(int count) {
7205f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7215f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal += count;
7225f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7235f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7245f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7255f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks seen when watchdog triggered
7265f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7275f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogAvailableNetworksTotal(int count) {
7285f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7295f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal += count;
7305f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7315f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7325f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7335f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment count of triggers with atleast one bad association network
7345f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7355f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggersWithBadAssociation() {
7365f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7375f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation++;
7385f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7395f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7405f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7415f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment count of triggers with atleast one bad authentication network
7425f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7435f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggersWithBadAuthentication() {
7445f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7455f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication++;
7465f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7475f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7485f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7495f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment count of triggers with atleast one bad dhcp network
7505f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7515f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggersWithBadDhcp() {
7525f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7535f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp++;
7545f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7555f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7565f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7575f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment count of triggers with atleast one bad other network
7585f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7595f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggersWithBadOther() {
7605f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7615f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggersWithBadOther++;
7625f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7635f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7645f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne
7655f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
766ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     * Increment number of times connectivity watchdog confirmed pno is working
767ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     */
768ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    public void incrementNumConnectivityWatchdogPnoGood() {
769ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        synchronized (mLock) {
770ce003b812aead64dcb36647180991150021b24c1Glen Kuhne            mWifiLogProto.numConnectivityWatchdogPnoGood++;
771ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        }
772ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    }
773ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    /**
774ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     * Increment number of times connectivity watchdog found pno not working
775ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     */
776ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    public void incrementNumConnectivityWatchdogPnoBad() {
777ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        synchronized (mLock) {
778ce003b812aead64dcb36647180991150021b24c1Glen Kuhne            mWifiLogProto.numConnectivityWatchdogPnoBad++;
779ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        }
780ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    }
781ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    /**
782ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     * Increment number of times connectivity watchdog confirmed background scan is working
783ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     */
784ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    public void incrementNumConnectivityWatchdogBackgroundGood() {
785ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        synchronized (mLock) {
786ce003b812aead64dcb36647180991150021b24c1Glen Kuhne            mWifiLogProto.numConnectivityWatchdogBackgroundGood++;
787ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        }
788ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    }
789ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    /**
790ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     * Increment number of times connectivity watchdog found background scan not working
791ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     */
792ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    public void incrementNumConnectivityWatchdogBackgroundBad() {
793ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        synchronized (mLock) {
794ce003b812aead64dcb36647180991150021b24c1Glen Kuhne            mWifiLogProto.numConnectivityWatchdogBackgroundBad++;
795ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        }
796ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    }
797ce003b812aead64dcb36647180991150021b24c1Glen Kuhne
7987a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    /**
7997a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne     * Increment occurence count of RSSI level from RSSI poll.
8007a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne     * Ignores rssi values outside the bounds of [MIN_RSSI_POLL, MAX_RSSI_POLL]
8017a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne     */
8027a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    public void incrementRssiPollRssiCount(int rssi) {
8037a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne        if (!(rssi >= MIN_RSSI_POLL && rssi <= MAX_RSSI_POLL)) {
8047a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            return;
8057a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne        }
8067a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne        synchronized (mLock) {
8077a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            int count = mRssiPollCounts.get(rssi);
8087a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            mRssiPollCounts.put(rssi, count + 1);
8097a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne        }
8107a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne    }
8117a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne
812da22e3d28b62005dce5fddd75207bd3d7a1745e1Glen Kuhne    /**
813f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal     * Increments the count of alerts by alert reason.
814f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal     *
815f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal     * @param reason The cause of the alert. The reason values are driver-specific.
816f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal     */
817f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal    public void incrementAlertReasonCount(int reason) {
818f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal        if (reason > WifiLoggerHal.WIFI_ALERT_REASON_MAX
819f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                || reason < WifiLoggerHal.WIFI_ALERT_REASON_MIN) {
820f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            reason = WifiLoggerHal.WIFI_ALERT_REASON_RESERVED;
821f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal        }
822f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal        synchronized (mLock) {
823f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            int alertCount = mWifiAlertReasonCounts.get(reason);
824f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            mWifiAlertReasonCounts.put(reason, alertCount + 1);
825f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal        }
826f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal    }
827f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal
828f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal    /**
829da22e3d28b62005dce5fddd75207bd3d7a1745e1Glen Kuhne     * Increment count of Watchdog successes.
830da22e3d28b62005dce5fddd75207bd3d7a1745e1Glen Kuhne     */
831da22e3d28b62005dce5fddd75207bd3d7a1745e1Glen Kuhne    public void incrementNumLastResortWatchdogSuccesses() {
832da22e3d28b62005dce5fddd75207bd3d7a1745e1Glen Kuhne        synchronized (mLock) {
833da22e3d28b62005dce5fddd75207bd3d7a1745e1Glen Kuhne            mWifiLogProto.numLastResortWatchdogSuccesses++;
834da22e3d28b62005dce5fddd75207bd3d7a1745e1Glen Kuhne        }
835da22e3d28b62005dce5fddd75207bd3d7a1745e1Glen Kuhne    }
836da22e3d28b62005dce5fddd75207bd3d7a1745e1Glen Kuhne
83711638f348ba45f9f417928e79b81186cef76c561Glen Kuhne    public static final String PROTO_DUMP_ARG = "wifiMetricsProto";
8381b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
8391b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Dump all WifiMetrics. Collects some metrics from ConfigStore, Settings and WifiManager
8401b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * at this time
8411b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
8421b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param fd unused
8431b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param pw PrintWriter for writing dump to
8441b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param args unused
8451b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
8461b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8471b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
8481b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            pw.println("WifiMetrics:");
84911638f348ba45f9f417928e79b81186cef76c561Glen Kuhne            if (args.length > 0 && PROTO_DUMP_ARG.equals(args[0])) {
8501b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                //Dump serialized WifiLog proto
8511b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                consolidateProto(true);
8521b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                for (ConnectionEvent event : mConnectionEventList) {
8531b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    if (mCurrentConnectionEvent != event) {
8541b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        //indicate that automatic bug report has been taken for all valid
8551b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        //connection events
8561b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        event.mConnectionEvent.automaticBugReportTaken = true;
8571b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    }
8581b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                }
8591b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                byte[] wifiMetricsProto = WifiMetricsProto.WifiLog.toByteArray(mWifiLogProto);
8601b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                String metricsProtoDump = Base64.encodeToString(wifiMetricsProto, Base64.DEFAULT);
8611b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println(metricsProtoDump);
8621b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("EndWifiMetrics");
8632532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                clear();
8641b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            } else {
8651b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mConnectionEvents:");
8661b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                for (ConnectionEvent event : mConnectionEventList) {
8671b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    String eventLine = event.toString();
8681b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    if (event == mCurrentConnectionEvent) {
8691b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        eventLine += "CURRENTLY OPEN EVENT";
8701b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    }
8711b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    pw.println(eventLine);
8721b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                }
8731b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.numSavedNetworks=" + mWifiLogProto.numSavedNetworks);
8741b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.numOpenNetworks=" + mWifiLogProto.numOpenNetworks);
8751b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.numPersonalNetworks="
8761b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        + mWifiLogProto.numPersonalNetworks);
8771b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.numEnterpriseNetworks="
8781b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        + mWifiLogProto.numEnterpriseNetworks);
8791b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.isLocationEnabled=" + mWifiLogProto.isLocationEnabled);
8801b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.isScanningAlwaysEnabled="
8811b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        + mWifiLogProto.isScanningAlwaysEnabled);
882c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numNetworksAddedByUser="
883c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numNetworksAddedByUser);
884c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numNetworksAddedByApps="
885c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numNetworksAddedByApps);
886c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numNonEmptyScanResults="
887c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numNonEmptyScanResults);
888c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numEmptyScanResults="
889c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numEmptyScanResults);
890c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numOneshotScans="
891c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numOneshotScans);
892c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numBackgroundScans="
893c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numBackgroundScans);
894c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
895c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mScanReturnEntries:");
896c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  SCAN_UNKNOWN: " + getScanReturnEntry(
897c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.SCAN_UNKNOWN));
898c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  SCAN_SUCCESS: " + getScanReturnEntry(
899c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.SCAN_SUCCESS));
900c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  SCAN_FAILURE_INTERRUPTED: " + getScanReturnEntry(
901c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED));
902c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  SCAN_FAILURE_INVALID_CONFIGURATION: " + getScanReturnEntry(
903c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION));
904c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  FAILURE_WIFI_DISABLED: " + getScanReturnEntry(
905c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.FAILURE_WIFI_DISABLED));
906c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
907c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mSystemStateEntries: <state><screenOn> : <scansInitiated>");
908c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_UNKNOWN       ON: "
909c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, true));
910c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_DISABLED      ON: "
911c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISABLED, true));
912c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_DISCONNECTED  ON: "
913c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED, true));
914c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_ASSOCIATED    ON: "
915c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, true));
916c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_UNKNOWN      OFF: "
917c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, false));
918c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_DISABLED     OFF: "
919c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISABLED, false));
920c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_DISCONNECTED OFF: "
921c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED, false));
922c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_ASSOCIATED   OFF: "
923c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, false));
924ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                pw.println("mWifiLogProto.numConnectivityWatchdogPnoGood="
925ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                        + mWifiLogProto.numConnectivityWatchdogPnoGood);
926ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                pw.println("mWifiLogProto.numConnectivityWatchdogPnoBad="
927ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                        + mWifiLogProto.numConnectivityWatchdogPnoBad);
928ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                pw.println("mWifiLogProto.numConnectivityWatchdogBackgroundGood="
929ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                        + mWifiLogProto.numConnectivityWatchdogBackgroundGood);
930ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                pw.println("mWifiLogProto.numConnectivityWatchdogBackgroundBad="
931ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                        + mWifiLogProto.numConnectivityWatchdogBackgroundBad);
9325f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggers="
9335f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggers);
9345f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal="
9355f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal);
9365f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal="
9375f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal);
9385f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal="
9395f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal);
9405f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal="
9415f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal);
9425f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal="
9435f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal);
9445f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation="
9455f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation);
9465f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication="
9475f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication);
9485f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp="
9495f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp);
9505f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadOther="
9515f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggersWithBadOther);
952da22e3d28b62005dce5fddd75207bd3d7a1745e1Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogSuccesses="
953da22e3d28b62005dce5fddd75207bd3d7a1745e1Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogSuccesses);
954107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne                pw.println("mWifiLogProto.recordDurationSec="
955107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne                        + ((mClock.getElapsedSinceBootMillis() / 1000) - mRecordStartTimeSec));
9567a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                pw.println("mWifiLogProto.rssiPollRssiCount: Printing counts for [" + MIN_RSSI_POLL
9577a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                        + ", " + MAX_RSSI_POLL + "]");
9587a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                StringBuilder sb = new StringBuilder();
9597a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                for (int i = MIN_RSSI_POLL; i <= MAX_RSSI_POLL; i++) {
9607a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                    sb.append(mRssiPollCounts.get(i) + " ");
9617a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                }
9627a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                pw.println("  " + sb.toString());
963f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                pw.print("mWifiLogProto.alertReasonCounts=");
964f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                sb.setLength(0);
965f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                for (int i = WifiLoggerHal.WIFI_ALERT_REASON_MIN;
966f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                        i <= WifiLoggerHal.WIFI_ALERT_REASON_MAX; i++) {
967f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                    int count = mWifiAlertReasonCounts.get(i);
968f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                    if (count > 0) {
969f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                        sb.append("(" + i + "," + count + "),");
970f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                    }
971f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                }
972f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                if (sb.length() > 1) {
973f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                    sb.setLength(sb.length() - 1);  // strip trailing comma
974f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                    pw.println(sb.toString());
975f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                } else {
976f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                    pw.println("()");
977f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                }
9781b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
9791b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
9801b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
9811b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
9821b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
983c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * append the separate ConnectionEvent, SystemStateEntry and ScanReturnCode collections to their
984c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * respective lists within mWifiLogProto
9851b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
9861b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param incremental Only include ConnectionEvents created since last automatic bug report
9871b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
9881b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    private void consolidateProto(boolean incremental) {
9891b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        List<WifiMetricsProto.ConnectionEvent> events = new ArrayList<>();
9907a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne        List<WifiMetricsProto.RssiPollCount> rssis = new ArrayList<>();
991f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal        List<WifiMetricsProto.AlertReasonCount> alertReasons = new ArrayList<>();
9921b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
9931b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            for (ConnectionEvent event : mConnectionEventList) {
994c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                // If this is not incremental, dump full ConnectionEvent list
995c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                // Else Dump all un-dumped events except for the current one
9961b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                if (!incremental || ((mCurrentConnectionEvent != event)
9971b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        && !event.mConnectionEvent.automaticBugReportTaken)) {
9981b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    //Get all ConnectionEvents that haven not been dumped as a proto, also exclude
9991b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    //the current active un-ended connection event
10001b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    events.add(event.mConnectionEvent);
1001c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    if (incremental) {
1002c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        event.mConnectionEvent.automaticBugReportTaken = true;
1003c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    }
10041b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                }
10051b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
10061b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            if (events.size() > 0) {
10071b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                mWifiLogProto.connectionEvent = events.toArray(mWifiLogProto.connectionEvent);
10081b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
1009c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
1010c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            //Convert the SparseIntArray of scanReturnEntry integers into ScanReturnEntry proto list
1011c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiLogProto.scanReturnEntries =
1012c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    new WifiMetricsProto.WifiLog.ScanReturnEntry[mScanReturnEntries.size()];
1013c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            for (int i = 0; i < mScanReturnEntries.size(); i++) {
1014c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.scanReturnEntries[i] = new WifiMetricsProto.WifiLog.ScanReturnEntry();
1015c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.scanReturnEntries[i].scanReturnCode = mScanReturnEntries.keyAt(i);
1016c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.scanReturnEntries[i].scanResultsCount = mScanReturnEntries.valueAt(i);
1017c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            }
1018c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
1019c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            // Convert the SparseIntArray of systemStateEntry into WifiSystemStateEntry proto list
1020c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            // This one is slightly more complex, as the Sparse are indexed with:
1021c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            //     key: wifiState * 2 + isScreenOn, value: wifiStateCount
1022c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiLogProto.wifiSystemStateEntries =
1023c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    new WifiMetricsProto.WifiLog
1024c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    .WifiSystemStateEntry[mWifiSystemStateEntries.size()];
1025c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            for (int i = 0; i < mWifiSystemStateEntries.size(); i++) {
1026c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.wifiSystemStateEntries[i] =
1027c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        new WifiMetricsProto.WifiLog.WifiSystemStateEntry();
1028c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.wifiSystemStateEntries[i].wifiState =
1029c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        mWifiSystemStateEntries.keyAt(i) / 2;
1030c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.wifiSystemStateEntries[i].wifiStateCount =
1031c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        mWifiSystemStateEntries.valueAt(i);
1032c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.wifiSystemStateEntries[i].isScreenOn =
1033c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        (mWifiSystemStateEntries.keyAt(i) % 2) > 0;
1034c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            }
1035107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne            mWifiLogProto.recordDurationSec = (int) ((mClock.getElapsedSinceBootMillis() / 1000)
1036107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne                    - mRecordStartTimeSec);
10377a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne
10387a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            /**
10397a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne             * Convert the SparseIntArray of RSSI poll rssi's and counts to the proto's repeated
10407a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne             * IntKeyVal array.
10417a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne             */
10427a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            for (int i = 0; i < mRssiPollCounts.size(); i++) {
10437a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                WifiMetricsProto.RssiPollCount keyVal = new WifiMetricsProto.RssiPollCount();
10447a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                keyVal.rssi = mRssiPollCounts.keyAt(i);
10457a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                keyVal.count = mRssiPollCounts.valueAt(i);
10467a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne                rssis.add(keyVal);
10477a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            }
10487a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            mWifiLogProto.rssiPollRssiCount = rssis.toArray(mWifiLogProto.rssiPollRssiCount);
1049f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal
1050f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            /**
1051f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal             * Convert the SparseIntArray of alert reasons and counts to the proto's repeated
1052f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal             * IntKeyVal array.
1053f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal             */
1054f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            for (int i = 0; i < mWifiAlertReasonCounts.size(); i++) {
1055f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                WifiMetricsProto.AlertReasonCount keyVal = new WifiMetricsProto.AlertReasonCount();
1056f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                keyVal.reason = mWifiAlertReasonCounts.keyAt(i);
1057f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                keyVal.count = mWifiAlertReasonCounts.valueAt(i);
1058f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal                alertReasons.add(keyVal);
1059f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            }
1060f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            mWifiLogProto.alertReasonCount = alertReasons.toArray(mWifiLogProto.alertReasonCount);
1061ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne        }
10621b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
10632532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne
10642532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    /**
10652532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne     * Clear all WifiMetrics, except for currentConnectionEvent.
10662532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne     */
10672532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    private void clear() {
10682532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        synchronized (mLock) {
10692532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mConnectionEventList.clear();
10702532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            if (mCurrentConnectionEvent != null) {
10712532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mConnectionEventList.add(mCurrentConnectionEvent);
10722532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            }
10732532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mScanReturnEntries.clear();
10742532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mWifiSystemStateEntries.clear();
1075107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne            mRecordStartTimeSec = mClock.getElapsedSinceBootMillis() / 1000;
10767a0b9ffe794113c4a5ed528d8aadeb3303d1b089Glen Kuhne            mRssiPollCounts.clear();
1077f11073c03746f1c79e6a316884bc59574b562a8bmukesh agrawal            mWifiAlertReasonCounts.clear();
10782532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mWifiLogProto.clear();
10792532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        }
10802532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    }
1081ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne
1082ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    /**
1083ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne     *  Set screen state (On/Off)
1084ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne     */
1085ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    public void setScreenState(boolean screenOn) {
1086ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        synchronized (mLock) {
1087ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mScreenOn = screenOn;
1088ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        }
1089ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    }
1090ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne
1091ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    /**
1092ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne     *  Set wifi state (WIFI_UNKNOWN, WIFI_DISABLED, WIFI_DISCONNECTED, WIFI_ASSOCIATED)
1093ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne     */
1094ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    public void setWifiState(int wifiState) {
1095ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        synchronized (mLock) {
1096ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mWifiState = wifiState;
1097ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        }
1098ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    }
10991b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne}
1100