WifiMetrics.java revision 947e55415eab3989f2f5cede0c03745cf9268309
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 192532a24b254d724a9b6771d327dc410b32b18602Glen Kuhneimport android.net.wifi.WifiConfiguration; 201b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport android.net.wifi.WifiInfo; 211b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport android.os.SystemClock; 221b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport android.util.Base64; 231b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport android.util.SparseArray; 241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 251b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.io.FileDescriptor; 261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.io.PrintWriter; 271b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.util.ArrayList; 281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.util.Calendar; 291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhneimport java.util.List; 301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne/** 321b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Provides storage for wireless connectivity metrics, as they are generated. 331b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Metrics logged by this class include: 341b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Aggregated connection stats (num of connections, num of failures, ...) 351b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Discrete connection event stats (time, duration, failure codes, ...) 361b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Router details (technology type, authentication type, ...) 371b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Scan stats 381b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 391b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhnepublic class WifiMetrics { 401b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne private static final String TAG = "WifiMetrics"; 411b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne private final Object mLock = new Object(); 422532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne private static final int MAX_CONNECTION_EVENTS = 256; 431b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 441b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Metrics are stored within an instance of the WifiLog proto during runtime, 451b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * The ConnectionEvent, SystemStateEntries & ScanReturnEntries metrics are stored during 461b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * runtime in member lists of this WifiMetrics class, with the final WifiLog proto being pieced 471b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * together at dump-time 481b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 491b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne private final WifiMetricsProto.WifiLog mWifiLogProto; 501b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 511b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Session information that gets logged for every Wifi connection attempt. 521b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 531b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne private final List<ConnectionEvent> mConnectionEventList; 541b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 551b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * The latest started (but un-ended) connection attempt 561b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 571b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne private ConnectionEvent mCurrentConnectionEvent; 581b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 591b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Count of number of times each scan return code, indexed by WifiLog.ScanReturnCode 601b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 611b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne private final SparseArray<WifiMetricsProto.WifiLog.ScanReturnEntry> mScanReturnEntries; 621b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 631b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Mapping of system state to the counts of scans requested in that wifi state * screenOn 641b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * combination. Indexed by WifiLog.WifiState * (1 + screenOn) 651b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 661b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne private final SparseArray<WifiMetricsProto.WifiLog.WifiSystemStateEntry> 671b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiSystemStateEntries; 681b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 691b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne class RouterFingerPrint { 701b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne private WifiMetricsProto.RouterFingerPrint mRouterFingerPrintProto; 712532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne RouterFingerPrint() { 721b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mRouterFingerPrintProto = new WifiMetricsProto.RouterFingerPrint(); 731b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 741b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 751b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne public String toString() { 761b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne StringBuilder sb = new StringBuilder(); 771b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 781b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append("mConnectionEvent.roamType=" + mRouterFingerPrintProto.roamType); 791b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(", mChannelInfo=" + mRouterFingerPrintProto.channelInfo); 801b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(", mDtim=" + mRouterFingerPrintProto.dtim); 811b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(", mAuthentication=" + mRouterFingerPrintProto.authentication); 821b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(", mHidden=" + mRouterFingerPrintProto.hidden); 831b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(", mRouterTechnology=" + mRouterFingerPrintProto.routerTechnology); 841b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(", mSupportsIpv6=" + mRouterFingerPrintProto.supportsIpv6); 851b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 861b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne return sb.toString(); 871b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 882532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne public void updateFromWifiConfiguration(WifiConfiguration config) { 892532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne if (config != null) { 902532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne /*<TODO> 912532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mRouterFingerPrintProto.roamType 922532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mRouterFingerPrintProto.routerTechnology 932532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mRouterFingerPrintProto.supportsIpv6 942532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne */ 952532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne if (config.allowedAuthAlgorithms != null 962532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne && config.allowedAuthAlgorithms.get(WifiConfiguration.AuthAlgorithm.OPEN)) { 972532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mRouterFingerPrintProto.authentication = 982532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne WifiMetricsProto.RouterFingerPrint.AUTH_OPEN; 992532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne } else if (config.isEnterprise()) { 1002532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mRouterFingerPrintProto.authentication = 1012532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE; 1022532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne } else { 1032532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mRouterFingerPrintProto.authentication = 1042532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL; 1052532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne } 1062532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mRouterFingerPrintProto.hidden = config.hiddenSSID; 1072532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mRouterFingerPrintProto.channelInfo = config.apChannel; 108947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne // Config may not have a valid dtimInterval set yet, in which case dtim will be zero 109947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne // (These are only populated from beacon frame scan results, which are returned as 110947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne // scan results from the chip far less frequently than Probe-responses) 111947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne if (config.dtimInterval > 0) { 112947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne mRouterFingerPrintProto.dtim = config.dtimInterval; 113947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne } 1142532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne } 1152532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne } 1161b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 1171b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 1181b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 1191b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Log event, tracking the start time, end time and result of a wireless connection attempt. 1201b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 1211b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne class ConnectionEvent { 1221b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne WifiMetricsProto.ConnectionEvent mConnectionEvent; 1231b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne RouterFingerPrint mRouterFingerPrint; 1241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne private long mRealStartTime; 1251b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 1261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Bitset tracking the capture completeness of this connection event bit 1='Event started', 1271b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * bit 2='Event ended' value = 3 for capture completeness 1281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 1291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne private int mEventCompleteness; 1301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne private long mRealEndTime; 1311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 1322532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne //<TODO> Move these constants into a wifi.proto Enum 1332532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne // Level 2 Failure Codes 1342532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne // Failure is unknown 1352532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne public static final int LLF_UNKNOWN = 0; 1362532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne // NONE 1372532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne public static final int LLF_NONE = 1; 1382532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne // ASSOCIATION_REJECTION_EVENT 1392532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne public static final int LLF_ASSOCIATION_REJECTION = 2; 1402532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne // AUTHENTICATION_FAILURE_EVENT 1412532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne public static final int LLF_AUTHENTICATION_FAILURE = 3; 1422532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne // SSID_TEMP_DISABLED (Also Auth failure) 1432532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne public static final int LLF_SSID_TEMP_DISABLED = 4; 1442532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne // CONNECT_NETWORK_FAILED 1452532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne public static final int LLF_CONNECT_NETWORK_FAILED = 5; 1462532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne // NETWORK_DISCONNECTION_EVENT 1472532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne public static final int LLF_NETWORK_DISCONNECTION = 6; 1482532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne 1491b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne private ConnectionEvent() { 1501b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mConnectionEvent = new WifiMetricsProto.ConnectionEvent(); 151947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne mRealEndTime = 0; 152947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne mRealStartTime = 0; 153947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne mEventCompleteness = 0; 1542532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mRouterFingerPrint = new RouterFingerPrint(); 1552532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mConnectionEvent.routerFingerprint = mRouterFingerPrint.mRouterFingerPrintProto; 1561b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 1571b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 1581b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne public String toString() { 1591b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne StringBuilder sb = new StringBuilder(); 1601b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append("startTime="); 1611b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne Calendar c = Calendar.getInstance(); 1621b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 1631b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne c.setTimeInMillis(mConnectionEvent.startTimeMillis); 1641b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(mConnectionEvent.startTimeMillis == 0 ? " <null>" : 1651b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)); 1661b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(", endTime="); 1671b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne c.setTimeInMillis(mRealEndTime); 1681b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(mRealEndTime == 0 ? " <null>" : 1691b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)); 1701b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(", durationTakenToConnectMillis="); 1711b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(mConnectionEvent.durationTakenToConnectMillis); 1722532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne sb.append(", roamType="); 1732532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne switch(mConnectionEvent.roamType){ 1742532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne case 1: 1752532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne sb.append("ROAM_NONE"); 1762532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne break; 1772532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne case 2: 1782532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne sb.append("ROAM_DBDC"); 1792532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne break; 1802532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne case 3: 1812532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne sb.append("ROAM_ENTERPRISE"); 1822532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne break; 1832532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne case 4: 1842532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne sb.append("ROAM_USER_SELECTED"); 1852532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne break; 1862532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne case 5: 1872532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne sb.append("ROAM_UNRELATED"); 1882532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne break; 1892532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne default: 1902532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne sb.append("ROAM_UNKNOWN"); 1912532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne } 1921b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(", level2FailureCode="); 1931b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(mConnectionEvent.level2FailureCode); 1941b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(", connectivityLevelFailureCode="); 1951b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(mConnectionEvent.connectivityLevelFailureCode); 1961b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(", mEventCompleteness="); 1971b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(mEventCompleteness); 1981b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append("\n "); 1992532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne sb.append("mRouterFingerprint: "); 2001b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne sb.append(mRouterFingerPrint.toString()); 2011b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2021b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne return sb.toString(); 2031b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2041b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2051b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 2061b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne public WifiMetrics() { 2071b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiLogProto = new WifiMetricsProto.WifiLog(); 2081b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mConnectionEventList = new ArrayList<>(); 2091b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mCurrentConnectionEvent = null; 2101b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mScanReturnEntries = new SparseArray<WifiMetricsProto.WifiLog.ScanReturnEntry>(); 2111b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiSystemStateEntries = new SparseArray<WifiMetricsProto.WifiLog.WifiSystemStateEntry>(); 2121b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2131b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 2141b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 2151b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Create a new connection event. Call when wifi attempts to make a new network connection 2161b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * If there is a current 'un-ended' connection event, it will be ended with UNKNOWN connectivity 2171b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * failure code. 2181b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Gathers and sets the RouterFingerPrint data as well 2191b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * 2201b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * @param wifiInfo WifiInfo for the current connection attempt, used for connection metrics 221947e55415eab3989f2f5cede0c03745cf9268309Glen Kuhne * @param config WifiConfiguration of the config used for the current connection attempt 2221b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * @param roamType Roam type that caused connection attempt, see WifiMetricsProto.WifiLog.ROAM_X 2231b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 2242532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne public void startConnectionEvent(WifiInfo wifiInfo, WifiConfiguration config, int roamType) { 2251b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 2262532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne if (mConnectionEventList.size() <= MAX_CONNECTION_EVENTS) { 2272532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent = new ConnectionEvent(); 2282532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent.mEventCompleteness |= 1; 2292532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent.mConnectionEvent.startTimeMillis = 2302532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne System.currentTimeMillis(); 2312532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent.mConnectionEvent.roamType = roamType; 2322532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent.mRouterFingerPrint.updateFromWifiConfiguration(config); 2332532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne if (wifiInfo != null) { 2342532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent.mConnectionEvent.signalStrength = wifiInfo.getRssi(); 2352532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne } 2362532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent.mRealStartTime = SystemClock.elapsedRealtime(); 2372532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mConnectionEventList.add(mCurrentConnectionEvent); 2381b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2391b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2401b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2411b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 2421b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne public void startConnectionEvent(WifiInfo wifiInfo) { 2432532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne startConnectionEvent(wifiInfo, null, WifiMetricsProto.ConnectionEvent.ROAM_NONE); 2441b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2451b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 2461b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 2472532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne * set the RoamType of the current ConnectionEvent (if any) 2482532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne */ 2492532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne public void setConnectionEventRoamType(int roamType) { 2502532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne if (mCurrentConnectionEvent != null) { 2512532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent.mConnectionEvent.roamType = roamType; 2522532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne } 2532532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne } 2542532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne /** 2551b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * End a Connection event record. Call when wifi connection attempt succeeds or fails. 2561b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * If a Connection event has not been started and is active when .end is called, a new one is 2571b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * created with zero duration. 2581b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * 2591b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * @param level2FailureCode Level 2 failure code returned by supplicant 2601b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * @param connectivityFailureCode WifiMetricsProto.ConnectionEvent.HLF_X 2611b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 2621b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne public void endConnectionEvent(int level2FailureCode, int connectivityFailureCode) { 2631b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 2642532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne if (mCurrentConnectionEvent != null) { 2652532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne boolean result = (level2FailureCode == 1) 2662532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne && (connectivityFailureCode == WifiMetricsProto.ConnectionEvent.HLF_NONE); 2672532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent.mConnectionEvent.connectionResult = result ? 1 : 0; 2682532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent.mEventCompleteness |= 2; 2692532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent.mRealEndTime = SystemClock.elapsedRealtime(); 2702532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent.mConnectionEvent.durationTakenToConnectMillis = (int) 2712532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne (mCurrentConnectionEvent.mRealEndTime 2722532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne - mCurrentConnectionEvent.mRealStartTime); 2732532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent.mConnectionEvent.level2FailureCode = level2FailureCode; 2742532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent.mConnectionEvent.connectivityLevelFailureCode = 2752532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne connectivityFailureCode; 2762532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne //ConnectionEvent already added to ConnectionEvents List 2772532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mCurrentConnectionEvent = null; 2781b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2791b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2801b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2811b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 2821b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne void setNumSavedNetworks(int num) { 2831b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 2841b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiLogProto.numSavedNetworks = num; 2851b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2861b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2871b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 2881b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne void setNumOpenNetworks(int num) { 2891b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 2901b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiLogProto.numOpenNetworks = num; 2911b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2921b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2931b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 2941b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne void setNumPersonalNetworks(int num) { 2951b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 2961b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiLogProto.numPersonalNetworks = num; 2971b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2981b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 2991b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 3001b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne void setNumEnterpriseNetworks(int num) { 3011b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 3021b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiLogProto.numEnterpriseNetworks = num; 3031b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3041b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3051b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 3061b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne void setNumNetworksAddedByUser(int num) { 3071b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 3081b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiLogProto.numNetworksAddedByUser = num; 3091b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3101b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3111b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 3121b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne void setNumNetworksAddedByApps(int num) { 3131b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 3141b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiLogProto.numNetworksAddedByApps = num; 3151b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3161b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3171b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 3181b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne void setIsLocationEnabled(boolean enabled) { 3191b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 3201b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiLogProto.isLocationEnabled = enabled; 3211b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3221b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3231b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 3241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne void setIsScanningAlwaysEnabled(boolean enabled) { 3251b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 3261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiLogProto.isScanningAlwaysEnabled = enabled; 3271b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 3301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 3311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Increment Airplane mode toggle count 3321b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 3331b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne public void incrementAirplaneToggleCount() { 3341b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 3351b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiLogProto.numWifiToggledViaAirplane++; 3361b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3371b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3381b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 3391b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 3401b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Increment Wifi Toggle count 3411b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 3421b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne public void incrementWifiToggleCount() { 3431b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 3441b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiLogProto.numWifiToggledViaSettings++; 3451b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3461b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3471b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 3481b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 3491b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Increment Non Empty Scan Results count 3501b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 3511b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne public void incrementNonEmptyScanResultCount() { 3521b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 3531b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiLogProto.numNonEmptyScanResults++; 3541b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3551b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3561b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 3571b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 3581b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Increment Empty Scan Results count 3591b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 3601b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne public void incrementEmptyScanResultCount() { 3611b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 3621b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiLogProto.numEmptyScanResults++; 3631b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3641b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3651b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 3661b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 3671b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Increment count of scan return code occurrence 3681b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * 3691b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * @param scanReturnCode Return code from scan attempt WifiMetricsProto.WifiLog.SCAN_X 3701b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 3711b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne public void incrementScanReturnEntry(int scanReturnCode) { 3721b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 3731b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne WifiMetricsProto.WifiLog.ScanReturnEntry entry = mScanReturnEntries.get(scanReturnCode); 3741b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne if (entry == null) { 3751b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne entry = new WifiMetricsProto.WifiLog.ScanReturnEntry(); 3761b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne entry.scanReturnCode = scanReturnCode; 3771b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne entry.scanResultsCount = 0; 3781b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3791b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne entry.scanResultsCount++; 3801b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mScanReturnEntries.put(scanReturnCode, entry); 3811b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3821b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 3831b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 3841b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 3851b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Increments the count of scans initiated by each wifi state, accounts for screenOn/Off 3861b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * 3871b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * @param state State of the system when scan was initiated, see WifiMetricsProto.WifiLog.WIFI_X 3881b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * @param screenOn Is the screen on 3891b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 3901b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne public void incrementWifiSystemScanStateCount(int state, boolean screenOn) { 3911b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 3921b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne int index = state * (screenOn ? 2 : 1); 3931b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne WifiMetricsProto.WifiLog.WifiSystemStateEntry entry = 3941b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiSystemStateEntries.get(index); 3951b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne if (entry == null) { 3961b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne entry = new WifiMetricsProto.WifiLog.WifiSystemStateEntry(); 3971b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne entry.wifiState = state; 3981b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne entry.wifiStateCount = 0; 3991b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne entry.isScreenOn = screenOn; 4001b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4011b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne entry.wifiStateCount++; 4021b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiSystemStateEntries.put(state, entry); 4031b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4041b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4051b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 40611638f348ba45f9f417928e79b81186cef76c561Glen Kuhne public static final String PROTO_DUMP_ARG = "wifiMetricsProto"; 4071b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 4081b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Dump all WifiMetrics. Collects some metrics from ConfigStore, Settings and WifiManager 4091b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * at this time 4101b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * 4111b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * @param fd unused 4121b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * @param pw PrintWriter for writing dump to 4131b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * @param args unused 4141b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 4151b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 4161b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 4171b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("WifiMetrics:"); 41811638f348ba45f9f417928e79b81186cef76c561Glen Kuhne if (args.length > 0 && PROTO_DUMP_ARG.equals(args[0])) { 4191b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne //Dump serialized WifiLog proto 4201b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne consolidateProto(true); 4211b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne for (ConnectionEvent event : mConnectionEventList) { 4221b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne if (mCurrentConnectionEvent != event) { 4231b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne //indicate that automatic bug report has been taken for all valid 4241b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne //connection events 4251b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne event.mConnectionEvent.automaticBugReportTaken = true; 4261b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4271b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4281b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne byte[] wifiMetricsProto = WifiMetricsProto.WifiLog.toByteArray(mWifiLogProto); 4291b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne String metricsProtoDump = Base64.encodeToString(wifiMetricsProto, Base64.DEFAULT); 4301b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println(metricsProtoDump); 4311b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("EndWifiMetrics"); 4322532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne clear(); 4331b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } else { 4341b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mConnectionEvents:"); 4351b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne for (ConnectionEvent event : mConnectionEventList) { 4361b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne String eventLine = event.toString(); 4371b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne if (event == mCurrentConnectionEvent) { 4381b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne eventLine += "CURRENTLY OPEN EVENT"; 4391b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4401b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println(eventLine); 4411b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4421b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mWifiLogProto.numSavedNetworks=" + mWifiLogProto.numSavedNetworks); 4431b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mWifiLogProto.numOpenNetworks=" + mWifiLogProto.numOpenNetworks); 4441b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mWifiLogProto.numPersonalNetworks=" 4451b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne + mWifiLogProto.numPersonalNetworks); 4461b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mWifiLogProto.numEnterpriseNetworks=" 4471b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne + mWifiLogProto.numEnterpriseNetworks); 4481b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mWifiLogProto.isLocationEnabled=" + mWifiLogProto.isLocationEnabled); 4491b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mWifiLogProto.isScanningAlwaysEnabled=" 4501b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne + mWifiLogProto.isScanningAlwaysEnabled); 4511b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mWifiLogProto.numWifiToggledViaSettings=" 4521b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne + mWifiLogProto.numWifiToggledViaSettings); 4531b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mWifiLogProto.numWifiToggledViaAirplane=" 4541b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne + mWifiLogProto.numWifiToggledViaAirplane); 4551b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mWifiLogProto.numNetworksAddedByUser=" 4561b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne + mWifiLogProto.numNetworksAddedByUser); 4571b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne //TODO - Pending scanning refactor 4581b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mWifiLogProto.numNetworksAddedByApps=" + "<TODO>"); 4591b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mWifiLogProto.numNonEmptyScanResults=" + "<TODO>"); 4601b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mWifiLogProto.numEmptyScanResults=" + "<TODO>"); 4611b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mWifiLogProto.numOneshotScans=" + "<TODO>"); 4621b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mWifiLogProto.numBackgroundScans=" + "<TODO>"); 4631b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mScanReturnEntries:" + " <TODO>"); 4641b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne pw.println("mSystemStateEntries:" + " <TODO>"); 4651b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4661b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4671b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4681b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 4691b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 4701b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Assign the separate ConnectionEvent, SystemStateEntry and ScanReturnCode lists to their 4711b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * respective lists within mWifiLogProto, and clear the original lists managed here. 4721b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * 4731b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * @param incremental Only include ConnectionEvents created since last automatic bug report 4741b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 4751b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne private void consolidateProto(boolean incremental) { 4761b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne List<WifiMetricsProto.ConnectionEvent> events = new ArrayList<>(); 4771b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne synchronized (mLock) { 4781b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne for (ConnectionEvent event : mConnectionEventList) { 4791b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne if (!incremental || ((mCurrentConnectionEvent != event) 4801b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne && !event.mConnectionEvent.automaticBugReportTaken)) { 4811b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne //Get all ConnectionEvents that haven not been dumped as a proto, also exclude 4821b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne //the current active un-ended connection event 4831b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne events.add(event.mConnectionEvent); 4842532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne event.mConnectionEvent.automaticBugReportTaken = true; 4851b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4861b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4871b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne if (events.size() > 0) { 4881b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne mWifiLogProto.connectionEvent = events.toArray(mWifiLogProto.connectionEvent); 4891b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4901b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne //<TODO> SystemStateEntry and ScanReturnCode list consolidation 4911b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4921b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 4931b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne 4941b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne /** 4951b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Serializes all of WifiMetrics to WifiLog proto, and returns the byte array. 4961b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * Does not count as taking an automatic bug report 4971b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * 4981b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne * @return byte array of the deserialized & consolidated Proto 4991b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne */ 5001b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne public byte[] toByteArray() { 5011b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne consolidateProto(false); 5021b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne return mWifiLogProto.toByteArray(mWifiLogProto); 5031b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne } 5042532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne 5052532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne /** 5062532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne * Clear all WifiMetrics, except for currentConnectionEvent. 5072532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne */ 5082532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne private void clear() { 5092532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne synchronized (mLock) { 5102532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mConnectionEventList.clear(); 5112532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne if (mCurrentConnectionEvent != null) { 5122532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mConnectionEventList.add(mCurrentConnectionEvent); 5132532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne } 5142532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mScanReturnEntries.clear(); 5152532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mWifiSystemStateEntries.clear(); 5162532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne mWifiLogProto.clear(); 5172532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne } 5182532a24b254d724a9b6771d327dc410b32b18602Glen Kuhne } 5191b067831bbff14f8e7a99b927b69f714d1b03448Glen Kuhne} 520