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;
451b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    private final Object mLock = new Object();
462532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    private static final int MAX_CONNECTION_EVENTS = 256;
4749410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne    private Clock mClock;
48ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    private boolean mScreenOn;
49ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    private int mWifiState;
501b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
511b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Metrics are stored within an instance of the WifiLog proto during runtime,
521b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * The ConnectionEvent, SystemStateEntries & ScanReturnEntries metrics are stored during
531b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * runtime in member lists of this WifiMetrics class, with the final WifiLog proto being pieced
541b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * together at dump-time
551b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
561b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    private final WifiMetricsProto.WifiLog mWifiLogProto;
571b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
581b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Session information that gets logged for every Wifi connection attempt.
591b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
601b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    private final List<ConnectionEvent> mConnectionEventList;
611b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
621b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * The latest started (but un-ended) connection attempt
631b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
641b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    private ConnectionEvent mCurrentConnectionEvent;
651b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
661b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Count of number of times each scan return code, indexed by WifiLog.ScanReturnCode
671b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
68c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private SparseIntArray mScanReturnEntries;
691b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
701b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Mapping of system state to the counts of scans requested in that wifi state * screenOn
711b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * combination. Indexed by WifiLog.WifiState * (1 + screenOn)
721b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
73c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private SparseIntArray mWifiSystemStateEntries;
7449410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne    /**
7549410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne     * Records the elapsedRealtime (in seconds) that represents the beginning of data
7649410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne     * capture for for this WifiMetricsProto
7749410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne     */
7849410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne    private long mRecordStartTimeSec;
791b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
801b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    class RouterFingerPrint {
811b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        private WifiMetricsProto.RouterFingerPrint mRouterFingerPrintProto;
822532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        RouterFingerPrint() {
831b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mRouterFingerPrintProto = new WifiMetricsProto.RouterFingerPrint();
841b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
851b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
861b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        public String toString() {
871b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            StringBuilder sb = new StringBuilder();
881b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            synchronized (mLock) {
891b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append("mConnectionEvent.roamType=" + mRouterFingerPrintProto.roamType);
901b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mChannelInfo=" + mRouterFingerPrintProto.channelInfo);
911b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mDtim=" + mRouterFingerPrintProto.dtim);
921b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mAuthentication=" + mRouterFingerPrintProto.authentication);
931b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mHidden=" + mRouterFingerPrintProto.hidden);
941b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mRouterTechnology=" + mRouterFingerPrintProto.routerTechnology);
951b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", mSupportsIpv6=" + mRouterFingerPrintProto.supportsIpv6);
961b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
971b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            return sb.toString();
981b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
992532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        public void updateFromWifiConfiguration(WifiConfiguration config) {
100ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne            synchronized (mLock) {
101ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                if (config != null) {
102ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // Is this a hidden network
103ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    mRouterFingerPrintProto.hidden = config.hiddenSSID;
104ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // Config may not have a valid dtimInterval set yet, in which case dtim will be zero
105ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // (These are only populated from beacon frame scan results, which are returned as
106ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // scan results from the chip far less frequently than Probe-responses)
107ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    if (config.dtimInterval > 0) {
108ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        mRouterFingerPrintProto.dtim = config.dtimInterval;
109ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    }
110ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    mCurrentConnectionEvent.mConfigSsid = config.SSID;
111ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // Get AuthType information from config (We do this again from ScanResult after
112ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // associating with BSSID)
113ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    if (config.allowedKeyManagement != null
114ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                            && config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) {
115ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
116ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                                .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_OPEN;
117ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    } else if (config.isEnterprise()) {
118ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
119ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                                .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE;
120ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    } else {
121ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
122ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                                .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL;
123ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    }
124ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // If there's a ScanResult candidate associated with this config already, get it and
125ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    // log (more accurate) metrics from it
126ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    ScanResult candidate = config.getNetworkSelectionStatus().getCandidate();
127ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    if (candidate != null) {
128ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        updateMetricsFromScanResult(candidate);
129ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    }
13096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                }
1312532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            }
1322532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        }
1331b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
1341b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
1351b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
1361b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Log event, tracking the start time, end time and result of a wireless connection attempt.
1371b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
1381b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    class ConnectionEvent {
1391b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        WifiMetricsProto.ConnectionEvent mConnectionEvent;
14096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        //<TODO> Move these constants into a wifi.proto Enum, and create a new Failure Type field
14196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        //covering more than just l2 failures. see b/27652362
14296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        /**
14396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne         * Failure codes, used for the 'level_2_failure_code' Connection event field (covers a lot
14496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne         * more failures than just l2 though, since the proto does not have a place to log
14596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne         * framework failures)
14696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne         */
1472532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // Failure is unknown
14896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_UNKNOWN = 0;
1492532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // NONE
15096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_NONE = 1;
1512532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // ASSOCIATION_REJECTION_EVENT
15296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_ASSOCIATION_REJECTION = 2;
1532532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // AUTHENTICATION_FAILURE_EVENT
15496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_AUTHENTICATION_FAILURE = 3;
1552532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // SSID_TEMP_DISABLED (Also Auth failure)
15696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_SSID_TEMP_DISABLED = 4;
1574dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        // reconnect() or reassociate() call to WifiNative failed
15896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_CONNECT_NETWORK_FAILED = 5;
1592532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        // NETWORK_DISCONNECTION_EVENT
16096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_NETWORK_DISCONNECTION = 6;
1614dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        // NEW_CONNECTION_ATTEMPT before previous finished
16296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_NEW_CONNECTION_ATTEMPT = 7;
16396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        // New connection attempt to the same network & bssid
16496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_REDUNDANT_CONNECTION_ATTEMPT = 8;
16596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        // Roam Watchdog timer triggered (Roaming timed out)
16696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_ROAM_TIMEOUT = 9;
16796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        // DHCP failure
16896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        public static final int FAILURE_DHCP = 10;
16996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne
1704dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        RouterFingerPrint mRouterFingerPrint;
1714dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        private long mRealStartTime;
1724dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        private long mRealEndTime;
1734dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        private String mConfigSsid;
1744dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne        private String mConfigBssid;
175ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        private int mWifiState;
176ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        private boolean mScreenOn;
1772532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne
1781b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        private ConnectionEvent() {
1791b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mConnectionEvent = new WifiMetricsProto.ConnectionEvent();
180947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne            mRealEndTime = 0;
181947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne            mRealStartTime = 0;
1822532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mRouterFingerPrint = new RouterFingerPrint();
1832532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mConnectionEvent.routerFingerprint = mRouterFingerPrint.mRouterFingerPrintProto;
1844dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mConfigSsid = "<NULL>";
1854dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mConfigBssid = "<NULL>";
186ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mWifiState = WifiMetricsProto.WifiLog.WIFI_UNKNOWN;
187ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mScreenOn = false;
1881b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
1891b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
1901b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        public String toString() {
1911b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            StringBuilder sb = new StringBuilder();
1921b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            sb.append("startTime=");
1931b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            Calendar c = Calendar.getInstance();
1941b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            synchronized (mLock) {
1951b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                c.setTimeInMillis(mConnectionEvent.startTimeMillis);
1961b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(mConnectionEvent.startTimeMillis == 0 ? "            <null>" :
1971b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c));
1984dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", SSID=");
1994dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(mConfigSsid);
2004dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", BSSID=");
2014dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(mConfigBssid);
2024dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", durationMillis=");
2031b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(mConnectionEvent.durationTakenToConnectMillis);
2042532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                sb.append(", roamType=");
2054dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                switch(mConnectionEvent.roamType) {
2062532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 1:
2072532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_NONE");
2082532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2092532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 2:
2102532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_DBDC");
2112532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2122532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 3:
2132532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_ENTERPRISE");
2142532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2152532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 4:
2162532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_USER_SELECTED");
2172532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2182532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    case 5:
2192532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_UNRELATED");
2202532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        break;
2212532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                    default:
2222532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        sb.append("ROAM_UNKNOWN");
2232532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                }
2244dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", connectionResult=");
2254dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(mConnectionEvent.connectionResult);
2261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", level2FailureCode=");
2274dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                switch(mConnectionEvent.level2FailureCode) {
22896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_NONE:
2294dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NONE");
2304dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
23196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_ASSOCIATION_REJECTION:
2324dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("ASSOCIATION_REJECTION");
2334dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
23496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_AUTHENTICATION_FAILURE:
2354dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("AUTHENTICATION_FAILURE");
2364dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
23796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_SSID_TEMP_DISABLED:
2384dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("SSID_TEMP_DISABLED");
2394dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
24096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_CONNECT_NETWORK_FAILED:
2414dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("CONNECT_NETWORK_FAILED");
2424dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
24396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_NETWORK_DISCONNECTION:
2444dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NETWORK_DISCONNECTION");
2454dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
24696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_NEW_CONNECTION_ATTEMPT:
2474dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NEW_CONNECTION_ATTEMPT");
2484dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
24996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_REDUNDANT_CONNECTION_ATTEMPT:
25096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        sb.append("REDUNDANT_CONNECTION_ATTEMPT");
25196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        break;
25296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_ROAM_TIMEOUT:
25396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        sb.append("ROAM_TIMEOUT");
25496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        break;
25596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    case FAILURE_DHCP:
25696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        sb.append("DHCP");
2574dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    default:
2584dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("UNKNOWN");
2594dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
2604dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                }
2611b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(", connectivityLevelFailureCode=");
2624dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                switch(mConnectionEvent.connectivityLevelFailureCode) {
2634dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    case WifiMetricsProto.ConnectionEvent.HLF_NONE:
2644dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NONE");
2654dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
2664dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    case WifiMetricsProto.ConnectionEvent.HLF_DHCP:
2674dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("DHCP");
2684dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
2694dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    case WifiMetricsProto.ConnectionEvent.HLF_NO_INTERNET:
2704dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("NO_INTERNET");
2714dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
2724dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    case WifiMetricsProto.ConnectionEvent.HLF_UNWANTED:
2734dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("UNWANTED");
2744dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
2754dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                    default:
2764dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        sb.append("UNKNOWN");
2774dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                        break;
2784dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                }
2794dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(", signalStrength=");
2804dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                sb.append(mConnectionEvent.signalStrength);
281ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                sb.append(", wifiState=");
282ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                switch(mWifiState) {
283ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                    case WifiMetricsProto.WifiLog.WIFI_DISABLED:
284ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        sb.append("WIFI_DISABLED");
285ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        break;
286ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                    case WifiMetricsProto.WifiLog.WIFI_DISCONNECTED:
287ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        sb.append("WIFI_DISCONNECTED");
288ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        break;
289ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                    case WifiMetricsProto.WifiLog.WIFI_ASSOCIATED:
290ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        sb.append("WIFI_ASSOCIATED");
291ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        break;
292ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                    default:
293ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        sb.append("WIFI_UNKNOWN");
294ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                        break;
295ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                }
296ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                sb.append(", screenOn=");
297ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                sb.append(mScreenOn);
298ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne                sb.append(". mRouterFingerprint: ");
2991b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                sb.append(mRouterFingerPrint.toString());
3001b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
3011b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            return sb.toString();
3021b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
3031b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
3041b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
30549410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne    public WifiMetrics(Clock clock) {
30649410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne        mClock = clock;
3071b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        mWifiLogProto = new WifiMetricsProto.WifiLog();
3081b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        mConnectionEventList = new ArrayList<>();
309c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        mScanReturnEntries = new SparseIntArray();
310c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        mWifiSystemStateEntries = new SparseIntArray();
3111b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        mCurrentConnectionEvent = null;
312ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        mScreenOn = true;
313ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        mWifiState = WifiMetricsProto.WifiLog.WIFI_DISABLED;
31449410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne        mRecordStartTimeSec = mClock.elapsedRealtime() / 1000;
3151b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
3161b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
317c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    // Values used for indexing SystemStateEntries
318c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private static final int SCREEN_ON = 1;
319c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private static final int SCREEN_OFF = 0;
320c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
3211b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
3221b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Create a new connection event. Call when wifi attempts to make a new network connection
3231b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * If there is a current 'un-ended' connection event, it will be ended with UNKNOWN connectivity
3241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * failure code.
3251b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Gathers and sets the RouterFingerPrint data as well
3261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
327947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne     * @param config WifiConfiguration of the config used for the current connection attempt
3281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param roamType Roam type that caused connection attempt, see WifiMetricsProto.WifiLog.ROAM_X
3291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
33096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne    public void startConnectionEvent(WifiConfiguration config, String targetBSSID, int roamType) {
3311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
33296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            // Check if this is overlapping another current connection event
33396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            if (mCurrentConnectionEvent != null) {
33496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                //Is this new Connection Event the same as the current one
33596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                if (mCurrentConnectionEvent.mConfigSsid != null
33696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        && mCurrentConnectionEvent.mConfigBssid != null
33796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        && config != null
33896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        && mCurrentConnectionEvent.mConfigSsid.equals(config.SSID)
33996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        && (mCurrentConnectionEvent.mConfigBssid.equals("any")
34096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                        || mCurrentConnectionEvent.mConfigBssid.equals(targetBSSID))) {
34196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    mCurrentConnectionEvent.mConfigBssid = targetBSSID;
34296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    // End Connection Event due to new connection attempt to the same network
34396cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    endConnectionEvent(ConnectionEvent.FAILURE_REDUNDANT_CONNECTION_ATTEMPT,
34496cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                            WifiMetricsProto.ConnectionEvent.HLF_NONE);
34596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                } else {
34696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    // End Connection Event due to new connection attempt to different network
34796cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                    endConnectionEvent(ConnectionEvent.FAILURE_NEW_CONNECTION_ATTEMPT,
34896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                            WifiMetricsProto.ConnectionEvent.HLF_NONE);
34996cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                }
35096cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            }
35196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            //If past maximum connection events, start removing the oldest
3524dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            while(mConnectionEventList.size() >= MAX_CONNECTION_EVENTS) {
3534dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne                mConnectionEventList.remove(0);
3544dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            }
3554dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mCurrentConnectionEvent = new ConnectionEvent();
3564dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mCurrentConnectionEvent.mConnectionEvent.startTimeMillis =
35749410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne                    mClock.currentTimeMillis();
35896cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            mCurrentConnectionEvent.mConfigBssid = targetBSSID;
3594dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mCurrentConnectionEvent.mConnectionEvent.roamType = roamType;
3604dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mCurrentConnectionEvent.mRouterFingerPrint.updateFromWifiConfiguration(config);
36196cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne            mCurrentConnectionEvent.mConfigBssid = "any";
36249410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne            mCurrentConnectionEvent.mRealStartTime = mClock.elapsedRealtime();
363ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mCurrentConnectionEvent.mWifiState = mWifiState;
364ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mCurrentConnectionEvent.mScreenOn = mScreenOn;
3654dead162c5336443e9d7b3deae5eb26b07d39254Glen Kuhne            mConnectionEventList.add(mCurrentConnectionEvent);
3661b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
3671b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
3681b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
3691b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
3702532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne     * set the RoamType of the current ConnectionEvent (if any)
3712532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne     */
3722532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    public void setConnectionEventRoamType(int roamType) {
373ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne        synchronized (mLock) {
374ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne            if (mCurrentConnectionEvent != null) {
375ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.roamType = roamType;
376ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne            }
3772532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        }
3782532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    }
379f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne
380f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne    /**
381f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne     * Set AP related metrics from ScanDetail
382f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne     */
383f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne    public void setConnectionScanDetail(ScanDetail scanDetail) {
384ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne        synchronized (mLock) {
385ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne            if (mCurrentConnectionEvent != null && scanDetail != null) {
386ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                NetworkDetail networkDetail = scanDetail.getNetworkDetail();
387ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                ScanResult scanResult = scanDetail.getScanResult();
388ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                //Ensure that we have a networkDetail, and that it corresponds to the currently
389ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                //tracked connection attempt
390ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                if (networkDetail != null && scanResult != null
391ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        && mCurrentConnectionEvent.mConfigSsid != null
392ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        && mCurrentConnectionEvent.mConfigSsid
393ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                        .equals("\"" + networkDetail.getSSID() + "\"")) {
394ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    updateMetricsFromNetworkDetail(networkDetail);
395ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                    updateMetricsFromScanResult(scanResult);
396ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne                }
397f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne            }
398f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne        }
399f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne    }
400f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne
4012532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    /**
4021b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * End a Connection event record. Call when wifi connection attempt succeeds or fails.
4031b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * If a Connection event has not been started and is active when .end is called, a new one is
4041b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * created with zero duration.
4051b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
4061b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param level2FailureCode Level 2 failure code returned by supplicant
4071b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param connectivityFailureCode WifiMetricsProto.ConnectionEvent.HLF_X
4081b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
4091b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void endConnectionEvent(int level2FailureCode, int connectivityFailureCode) {
4101b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
4112532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            if (mCurrentConnectionEvent != null) {
4122532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                boolean result = (level2FailureCode == 1)
4132532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        && (connectivityFailureCode == WifiMetricsProto.ConnectionEvent.HLF_NONE);
4142532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.connectionResult = result ? 1 : 0;
41549410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne                mCurrentConnectionEvent.mRealEndTime = mClock.elapsedRealtime();
4162532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.durationTakenToConnectMillis = (int)
4172532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        (mCurrentConnectionEvent.mRealEndTime
4182532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        - mCurrentConnectionEvent.mRealStartTime);
4192532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.level2FailureCode = level2FailureCode;
4202532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent.mConnectionEvent.connectivityLevelFailureCode =
4212532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                        connectivityFailureCode;
422f5cc6a0c7ede374b33de1cf5156bf149e2e76c13Glen Kuhne                // ConnectionEvent already added to ConnectionEvents List. Safe to null current here
4232532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mCurrentConnectionEvent = null;
4241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
4251b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
4261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
4271b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
4282b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    /**
4292b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne     * Set ConnectionEvent DTIM Interval (if set), and 802.11 Connection mode, from NetworkDetail
4302b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne     */
4312b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    private void updateMetricsFromNetworkDetail(NetworkDetail networkDetail) {
4322b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        int dtimInterval = networkDetail.getDtimInterval();
4332b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        if (dtimInterval > 0) {
4342b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.dtim =
4352b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                    dtimInterval;
4362b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        }
4372b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        int connectionWifiMode;
4382b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        switch (networkDetail.getWifiMode()) {
4392b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_UNDEFINED:
4402b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_UNKNOWN;
4412b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
4422b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11A:
4432b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_A;
4442b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
4452b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11B:
4462b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_B;
4472b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
4482b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11G:
4492b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_G;
4502b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
4512b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11N:
4522b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_N;
4532b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
4542b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            case InformationElementUtil.WifiMode.MODE_11AC  :
4552b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_AC;
4562b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
4572b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            default:
4582b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_OTHER;
4592b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                break;
4602b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        }
4612b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto
4622b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                .routerTechnology = connectionWifiMode;
4632b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    }
4642b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne
4652b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    /**
4662b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne     * Set ConnectionEvent RSSI and authentication type from ScanResult
4672b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne     */
4682b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    private void updateMetricsFromScanResult(ScanResult scanResult) {
4692b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        mCurrentConnectionEvent.mConnectionEvent.signalStrength = scanResult.level;
4702b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication =
4712b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                WifiMetricsProto.RouterFingerPrint.AUTH_OPEN;
47296cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        mCurrentConnectionEvent.mConfigBssid = scanResult.BSSID;
4732b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        if (scanResult.capabilities != null) {
4742b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            if (scanResult.capabilities.contains("WEP")) {
4752b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication =
4762b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                        WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL;
4772b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            } else if (scanResult.capabilities.contains("PSK")) {
4782b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication =
4792b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                        WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL;
4802b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            } else if (scanResult.capabilities.contains("EAP")) {
4812b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication =
4822b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne                        WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE;
4832b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne            }
4842b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne        }
48596cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne        mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.channelInfo =
48696cdfc0acafef88832515ecc52c01638c1493211Glen Kuhne                scanResult.frequency;
4872b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne    }
4882b152feb1c574f30557581770d4f8c06c770ba34Glen Kuhne
4891b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setNumSavedNetworks(int num) {
4901b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
4911b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numSavedNetworks = num;
4921b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
4931b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
4941b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
4951b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setNumOpenNetworks(int num) {
4961b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
4971b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numOpenNetworks = num;
4981b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
4991b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5001b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5011b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setNumPersonalNetworks(int num) {
5021b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5031b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numPersonalNetworks = num;
5041b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5051b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5061b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5071b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setNumEnterpriseNetworks(int num) {
5081b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5091b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numEnterpriseNetworks = num;
5101b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5111b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5121b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5131b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setNumNetworksAddedByUser(int num) {
5141b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5151b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numNetworksAddedByUser = num;
5161b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5171b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5181b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5191b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setNumNetworksAddedByApps(int num) {
5201b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5211b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numNetworksAddedByApps = num;
5221b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5231b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5251b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setIsLocationEnabled(boolean enabled) {
5261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5271b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.isLocationEnabled = enabled;
5281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    void setIsScanningAlwaysEnabled(boolean enabled) {
5321b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5331b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.isScanningAlwaysEnabled = enabled;
5341b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5351b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5361b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5371b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
5381b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Increment Non Empty Scan Results count
5391b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
5401b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void incrementNonEmptyScanResultCount() {
541c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        if (DBG) Log.v(TAG, "incrementNonEmptyScanResultCount");
5421b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5431b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numNonEmptyScanResults++;
5441b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5451b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5461b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5471b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
5481b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Increment Empty Scan Results count
5491b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
5501b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void incrementEmptyScanResultCount() {
551c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        if (DBG) Log.v(TAG, "incrementEmptyScanResultCount");
5521b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
5531b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mWifiLogProto.numEmptyScanResults++;
5541b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
5551b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
5561b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
5571b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
558c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Increment background scan count
559c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
560c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public void incrementBackgroundScanCount() {
561c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        if (DBG) Log.v(TAG, "incrementBackgroundScanCount");
562c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
563c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiLogProto.numBackgroundScans++;
564c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
565c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
566c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
567c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne   /**
568c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Get Background scan count
569c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
570c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public int getBackgroundScanCount() {
571c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
572c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            return mWifiLogProto.numBackgroundScans;
573c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
574c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
575c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
576c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
57770ce5a4cbaf5aaccd4e542e7bb87196fb4464a6eGlen Kuhne     * Increment oneshot scan count, and the associated WifiSystemScanStateCount entry
578c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
579c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public void incrementOneshotScanCount() {
580c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
581c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiLogProto.numOneshotScans++;
582c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
58370ce5a4cbaf5aaccd4e542e7bb87196fb4464a6eGlen Kuhne        incrementWifiSystemScanStateCount(mWifiState, mScreenOn);
584c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
585c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
586c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
587c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Get oneshot scan count
588c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
589c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public int getOneshotScanCount() {
590c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
591c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            return mWifiLogProto.numOneshotScans;
592c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
593c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
594c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
595c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private String returnCodeToString(int scanReturnCode) {
596c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        switch(scanReturnCode){
597c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.SCAN_UNKNOWN:
598c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "SCAN_UNKNOWN";
599c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.SCAN_SUCCESS:
600c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "SCAN_SUCCESS";
601c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED:
602c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "SCAN_FAILURE_INTERRUPTED";
603c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION:
604c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "SCAN_FAILURE_INVALID_CONFIGURATION";
605c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.FAILURE_WIFI_DISABLED:
606c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "FAILURE_WIFI_DISABLED";
607c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            default:
608c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "<UNKNOWN>";
609c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
610c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
611c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
612c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
6131b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Increment count of scan return code occurrence
6141b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
6151b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param scanReturnCode Return code from scan attempt WifiMetricsProto.WifiLog.SCAN_X
6161b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
617c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public void incrementScanReturnEntry(int scanReturnCode, int countToAdd) {
6181b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
619c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            if (DBG) Log.v(TAG, "incrementScanReturnEntry " + returnCodeToString(scanReturnCode));
620c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            int entry = mScanReturnEntries.get(scanReturnCode);
621c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            entry += countToAdd;
6221b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            mScanReturnEntries.put(scanReturnCode, entry);
6231b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
6241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
625c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
626c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Get the count of this scanReturnCode
627c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * @param scanReturnCode that we are getting the count for
628c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
629c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public int getScanReturnEntry(int scanReturnCode) {
630c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
631c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            return mScanReturnEntries.get(scanReturnCode);
632c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
633c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
634c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
635c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    private String wifiSystemStateToString(int state) {
636c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        switch(state){
637c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.WIFI_UNKNOWN:
638c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "WIFI_UNKNOWN";
639c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.WIFI_DISABLED:
640c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "WIFI_DISABLED";
641c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.WIFI_DISCONNECTED:
642c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "WIFI_DISCONNECTED";
643c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            case WifiMetricsProto.WifiLog.WIFI_ASSOCIATED:
644c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "WIFI_ASSOCIATED";
645c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            default:
646c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                return "default";
647c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
648c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
6491b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
6501b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
6511b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Increments the count of scans initiated by each wifi state, accounts for screenOn/Off
6521b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
6531b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param state State of the system when scan was initiated, see WifiMetricsProto.WifiLog.WIFI_X
6541b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param screenOn Is the screen on
6551b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
6561b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void incrementWifiSystemScanStateCount(int state, boolean screenOn) {
6571b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
658c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            if (DBG) {
659c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                Log.v(TAG, "incrementWifiSystemScanStateCount " + wifiSystemStateToString(state)
660c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + " " + screenOn);
6611b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
662c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            int index = (state * 2) + (screenOn ? SCREEN_ON : SCREEN_OFF);
663c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            int entry = mWifiSystemStateEntries.get(index);
664c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            entry++;
665c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiSystemStateEntries.put(index, entry);
666c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        }
667c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    }
668c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
669c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    /**
670c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * Get the count of this system State Entry
671c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     */
672c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne    public int getSystemStateCount(int state, boolean screenOn) {
673c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne        synchronized (mLock) {
674c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            int index = state * 2 + (screenOn ? SCREEN_ON : SCREEN_OFF);
675c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            return mWifiSystemStateEntries.get(index);
6761b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
6771b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
6781b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
679ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    /**
6805f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment number of times the Watchdog of Last Resort triggered, resetting the wifi stack
6815f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
6825f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggers() {
6835f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
6845f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggers++;
6855f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
6865f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
6875f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
6885f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks over bad association threshold when watchdog triggered
6895f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
6905f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogBadAssociationNetworksTotal(int count) {
6915f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
6925f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal += count;
6935f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
6945f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
6955f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
6965f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks over bad authentication threshold when watchdog triggered
6975f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
6985f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogBadAuthenticationNetworksTotal(int count) {
6995f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7005f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal += count;
7015f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7025f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7035f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7045f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks over bad dhcp threshold when watchdog triggered
7055f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7065f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogBadDhcpNetworksTotal(int count) {
7075f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7085f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal += count;
7095f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7105f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7115f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7125f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks over bad other threshold when watchdog triggered
7135f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7145f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogBadOtherNetworksTotal(int count) {
7155f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7165f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal += count;
7175f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7185f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7195f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7205f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * @param count number of networks seen when watchdog triggered
7215f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7225f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void addCountToNumLastResortWatchdogAvailableNetworksTotal(int count) {
7235f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7245f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal += count;
7255f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7265f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7275f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7285f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment count of triggers with atleast one bad association network
7295f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7305f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggersWithBadAssociation() {
7315f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7325f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation++;
7335f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7345f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7355f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7365f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment count of triggers with atleast one bad authentication network
7375f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7385f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggersWithBadAuthentication() {
7395f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7405f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication++;
7415f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7425f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7435f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7445f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment count of triggers with atleast one bad dhcp network
7455f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7465f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggersWithBadDhcp() {
7475f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7485f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp++;
7495f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7505f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7515f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
7525f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     * Increment count of triggers with atleast one bad other network
7535f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne     */
7545f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    public void incrementNumLastResortWatchdogTriggersWithBadOther() {
7555f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        synchronized (mLock) {
7565f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne            mWifiLogProto.numLastResortWatchdogTriggersWithBadOther++;
7575f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne        }
7585f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    }
7595f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne
7605f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne    /**
761ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     * Increment number of times connectivity watchdog confirmed pno is working
762ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     */
763ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    public void incrementNumConnectivityWatchdogPnoGood() {
764ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        synchronized (mLock) {
765ce003b812aead64dcb36647180991150021b24c1Glen Kuhne            mWifiLogProto.numConnectivityWatchdogPnoGood++;
766ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        }
767ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    }
768ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    /**
769ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     * Increment number of times connectivity watchdog found pno not working
770ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     */
771ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    public void incrementNumConnectivityWatchdogPnoBad() {
772ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        synchronized (mLock) {
773ce003b812aead64dcb36647180991150021b24c1Glen Kuhne            mWifiLogProto.numConnectivityWatchdogPnoBad++;
774ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        }
775ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    }
776ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    /**
777ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     * Increment number of times connectivity watchdog confirmed background scan is working
778ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     */
779ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    public void incrementNumConnectivityWatchdogBackgroundGood() {
780ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        synchronized (mLock) {
781ce003b812aead64dcb36647180991150021b24c1Glen Kuhne            mWifiLogProto.numConnectivityWatchdogBackgroundGood++;
782ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        }
783ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    }
784ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    /**
785ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     * Increment number of times connectivity watchdog found background scan not working
786ce003b812aead64dcb36647180991150021b24c1Glen Kuhne     */
787ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    public void incrementNumConnectivityWatchdogBackgroundBad() {
788ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        synchronized (mLock) {
789ce003b812aead64dcb36647180991150021b24c1Glen Kuhne            mWifiLogProto.numConnectivityWatchdogBackgroundBad++;
790ce003b812aead64dcb36647180991150021b24c1Glen Kuhne        }
791ce003b812aead64dcb36647180991150021b24c1Glen Kuhne    }
792ce003b812aead64dcb36647180991150021b24c1Glen Kuhne
79311638f348ba45f9f417928e79b81186cef76c561Glen Kuhne    public static final String PROTO_DUMP_ARG = "wifiMetricsProto";
7941b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
7951b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * Dump all WifiMetrics. Collects some metrics from ConfigStore, Settings and WifiManager
7961b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * at this time
7971b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
7981b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param fd unused
7991b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param pw PrintWriter for writing dump to
8001b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param args unused
8011b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
8021b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8031b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
8041b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            pw.println("WifiMetrics:");
80511638f348ba45f9f417928e79b81186cef76c561Glen Kuhne            if (args.length > 0 && PROTO_DUMP_ARG.equals(args[0])) {
8061b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                //Dump serialized WifiLog proto
8071b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                consolidateProto(true);
8081b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                for (ConnectionEvent event : mConnectionEventList) {
8091b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    if (mCurrentConnectionEvent != event) {
8101b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        //indicate that automatic bug report has been taken for all valid
8111b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        //connection events
8121b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        event.mConnectionEvent.automaticBugReportTaken = true;
8131b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    }
8141b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                }
8151b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                byte[] wifiMetricsProto = WifiMetricsProto.WifiLog.toByteArray(mWifiLogProto);
8161b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                String metricsProtoDump = Base64.encodeToString(wifiMetricsProto, Base64.DEFAULT);
8171b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println(metricsProtoDump);
8181b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("EndWifiMetrics");
8192532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                clear();
8201b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            } else {
8211b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mConnectionEvents:");
8221b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                for (ConnectionEvent event : mConnectionEventList) {
8231b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    String eventLine = event.toString();
8241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    if (event == mCurrentConnectionEvent) {
8251b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        eventLine += "CURRENTLY OPEN EVENT";
8261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    }
8271b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    pw.println(eventLine);
8281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                }
8291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.numSavedNetworks=" + mWifiLogProto.numSavedNetworks);
8301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.numOpenNetworks=" + mWifiLogProto.numOpenNetworks);
8311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.numPersonalNetworks="
8321b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        + mWifiLogProto.numPersonalNetworks);
8331b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.numEnterpriseNetworks="
8341b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        + mWifiLogProto.numEnterpriseNetworks);
8351b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.isLocationEnabled=" + mWifiLogProto.isLocationEnabled);
8361b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                pw.println("mWifiLogProto.isScanningAlwaysEnabled="
8371b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        + mWifiLogProto.isScanningAlwaysEnabled);
838c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numNetworksAddedByUser="
839c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numNetworksAddedByUser);
840c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numNetworksAddedByApps="
841c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numNetworksAddedByApps);
842c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numNonEmptyScanResults="
843c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numNonEmptyScanResults);
844c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numEmptyScanResults="
845c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numEmptyScanResults);
846c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numOneshotScans="
847c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numOneshotScans);
848c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mWifiLogProto.numBackgroundScans="
849c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + mWifiLogProto.numBackgroundScans);
850c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
851c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mScanReturnEntries:");
852c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  SCAN_UNKNOWN: " + getScanReturnEntry(
853c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.SCAN_UNKNOWN));
854c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  SCAN_SUCCESS: " + getScanReturnEntry(
855c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.SCAN_SUCCESS));
856c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  SCAN_FAILURE_INTERRUPTED: " + getScanReturnEntry(
857c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED));
858c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  SCAN_FAILURE_INVALID_CONFIGURATION: " + getScanReturnEntry(
859c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION));
860c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  FAILURE_WIFI_DISABLED: " + getScanReturnEntry(
861c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        WifiMetricsProto.WifiLog.FAILURE_WIFI_DISABLED));
862c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
863c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("mSystemStateEntries: <state><screenOn> : <scansInitiated>");
864c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_UNKNOWN       ON: "
865c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, true));
866c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_DISABLED      ON: "
867c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISABLED, true));
868c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_DISCONNECTED  ON: "
869c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED, true));
870c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_ASSOCIATED    ON: "
871c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, true));
872c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_UNKNOWN      OFF: "
873c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, false));
874c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_DISABLED     OFF: "
875c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISABLED, false));
876c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_DISCONNECTED OFF: "
877c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED, false));
878c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                pw.println("  WIFI_ASSOCIATED   OFF: "
879c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, false));
880ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                pw.println("mWifiLogProto.numConnectivityWatchdogPnoGood="
881ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                        + mWifiLogProto.numConnectivityWatchdogPnoGood);
882ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                pw.println("mWifiLogProto.numConnectivityWatchdogPnoBad="
883ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                        + mWifiLogProto.numConnectivityWatchdogPnoBad);
884ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                pw.println("mWifiLogProto.numConnectivityWatchdogBackgroundGood="
885ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                        + mWifiLogProto.numConnectivityWatchdogBackgroundGood);
886ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                pw.println("mWifiLogProto.numConnectivityWatchdogBackgroundBad="
887ce003b812aead64dcb36647180991150021b24c1Glen Kuhne                        + mWifiLogProto.numConnectivityWatchdogBackgroundBad);
8885f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggers="
8895f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggers);
8905f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal="
8915f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal);
8925f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal="
8935f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal);
8945f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal="
8955f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal);
8965f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal="
8975f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal);
8985f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal="
8995f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal);
9005f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation="
9015f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation);
9025f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication="
9035f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication);
9045f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp="
9055f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp);
9065f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadOther="
9075f001750a0ce82a8b3a47ac566117d4de27f3e23Glen Kuhne                        + mWifiLogProto.numLastResortWatchdogTriggersWithBadOther);
90849410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne                pw.println("mWifiLogProto.recordDurationSec="
90949410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne                        + ((mClock.elapsedRealtime() / 1000) - mRecordStartTimeSec));
9101b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
9111b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        }
9121b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
9131b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne
9141b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    /**
915c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * append the separate ConnectionEvent, SystemStateEntry and ScanReturnCode collections to their
916c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne     * respective lists within mWifiLogProto
9171b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     *
9181b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     * @param incremental Only include ConnectionEvents created since last automatic bug report
9191b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne     */
9201b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    private void consolidateProto(boolean incremental) {
9211b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        List<WifiMetricsProto.ConnectionEvent> events = new ArrayList<>();
9221b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne        synchronized (mLock) {
9231b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            for (ConnectionEvent event : mConnectionEventList) {
924c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                // If this is not incremental, dump full ConnectionEvent list
925c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                // Else Dump all un-dumped events except for the current one
9261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                if (!incremental || ((mCurrentConnectionEvent != event)
9271b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                        && !event.mConnectionEvent.automaticBugReportTaken)) {
9281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    //Get all ConnectionEvents that haven not been dumped as a proto, also exclude
9291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    //the current active un-ended connection event
9301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                    events.add(event.mConnectionEvent);
931c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    if (incremental) {
932c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        event.mConnectionEvent.automaticBugReportTaken = true;
933c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    }
9341b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                }
9351b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
9361b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            if (events.size() > 0) {
9371b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne                mWifiLogProto.connectionEvent = events.toArray(mWifiLogProto.connectionEvent);
9381b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne            }
939c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
940c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            //Convert the SparseIntArray of scanReturnEntry integers into ScanReturnEntry proto list
941c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiLogProto.scanReturnEntries =
942c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    new WifiMetricsProto.WifiLog.ScanReturnEntry[mScanReturnEntries.size()];
943c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            for (int i = 0; i < mScanReturnEntries.size(); i++) {
944c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.scanReturnEntries[i] = new WifiMetricsProto.WifiLog.ScanReturnEntry();
945c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.scanReturnEntries[i].scanReturnCode = mScanReturnEntries.keyAt(i);
946c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.scanReturnEntries[i].scanResultsCount = mScanReturnEntries.valueAt(i);
947c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            }
948c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne
949c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            // Convert the SparseIntArray of systemStateEntry into WifiSystemStateEntry proto list
950c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            // This one is slightly more complex, as the Sparse are indexed with:
951c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            //     key: wifiState * 2 + isScreenOn, value: wifiStateCount
952c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            mWifiLogProto.wifiSystemStateEntries =
953c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    new WifiMetricsProto.WifiLog
954c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                    .WifiSystemStateEntry[mWifiSystemStateEntries.size()];
955c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            for (int i = 0; i < mWifiSystemStateEntries.size(); i++) {
956c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.wifiSystemStateEntries[i] =
957c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        new WifiMetricsProto.WifiLog.WifiSystemStateEntry();
958c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.wifiSystemStateEntries[i].wifiState =
959c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        mWifiSystemStateEntries.keyAt(i) / 2;
960c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.wifiSystemStateEntries[i].wifiStateCount =
961c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        mWifiSystemStateEntries.valueAt(i);
962c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                mWifiLogProto.wifiSystemStateEntries[i].isScreenOn =
963c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne                        (mWifiSystemStateEntries.keyAt(i) % 2) > 0;
964c2c2648141e6190d85601ee8a6a1d0034e7ff927Glen Kuhne            }
96549410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne            mWifiLogProto.recordDurationSec = (int) ((mClock.elapsedRealtime() / 1000)
96649410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne                    - mRecordStartTimeSec);
967ebd663ff7027bbf19c4a5ed2bfb71b91bb925cd6Glen Kuhne        }
9681b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne    }
9692532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne
9702532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    /**
9712532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne     * Clear all WifiMetrics, except for currentConnectionEvent.
9722532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne     */
9732532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    private void clear() {
9742532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        synchronized (mLock) {
9752532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mConnectionEventList.clear();
9762532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            if (mCurrentConnectionEvent != null) {
9772532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne                mConnectionEventList.add(mCurrentConnectionEvent);
9782532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            }
9792532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mScanReturnEntries.clear();
9802532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mWifiSystemStateEntries.clear();
98149410c13ba2284fb7c836fd3527dc526ea5681a0Glen Kuhne            mRecordStartTimeSec = mClock.elapsedRealtime() / 1000;
9822532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne            mWifiLogProto.clear();
9832532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne        }
9842532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne    }
985ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne
986ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    /**
987ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne     *  Set screen state (On/Off)
988ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne     */
989ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    public void setScreenState(boolean screenOn) {
990ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        synchronized (mLock) {
991ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mScreenOn = screenOn;
992ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        }
993ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    }
994ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne
995ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    /**
996ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne     *  Set wifi state (WIFI_UNKNOWN, WIFI_DISABLED, WIFI_DISCONNECTED, WIFI_ASSOCIATED)
997ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne     */
998ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    public void setWifiState(int wifiState) {
999ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        synchronized (mLock) {
1000ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne            mWifiState = wifiState;
1001ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne        }
1002ea6fdf9a58f8ee83fba32c221331f10f9ec941e9Glen Kuhne    }
10031b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne}
1004