1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wifi; 18 19 import static java.lang.StrictMath.toIntExact; 20 21 import android.content.Context; 22 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback; 23 import android.net.NetworkAgent; 24 import android.net.wifi.EAPConstants; 25 import android.net.wifi.IOnWifiUsabilityStatsListener; 26 import android.net.wifi.ScanResult; 27 import android.net.wifi.SupplicantState; 28 import android.net.wifi.WifiConfiguration; 29 import android.net.wifi.WifiInfo; 30 import android.net.wifi.WifiManager; 31 import android.net.wifi.WifiManager.DeviceMobilityState; 32 import android.net.wifi.WifiUsabilityStatsEntry.ProbeStatus; 33 import android.net.wifi.hotspot2.PasspointConfiguration; 34 import android.net.wifi.hotspot2.ProvisioningCallback; 35 import android.os.Handler; 36 import android.os.IBinder; 37 import android.os.Looper; 38 import android.os.Message; 39 import android.os.RemoteException; 40 import android.os.SystemProperties; 41 import android.provider.Settings; 42 import android.telephony.TelephonyManager; 43 import android.util.ArrayMap; 44 import android.util.Base64; 45 import android.util.Log; 46 import android.util.Pair; 47 import android.util.SparseArray; 48 import android.util.SparseIntArray; 49 50 import com.android.internal.annotations.VisibleForTesting; 51 import com.android.server.wifi.aware.WifiAwareMetrics; 52 import com.android.server.wifi.hotspot2.ANQPNetworkKey; 53 import com.android.server.wifi.hotspot2.NetworkDetail; 54 import com.android.server.wifi.hotspot2.PasspointManager; 55 import com.android.server.wifi.hotspot2.PasspointMatch; 56 import com.android.server.wifi.hotspot2.PasspointProvider; 57 import com.android.server.wifi.hotspot2.Utils; 58 import com.android.server.wifi.nano.WifiMetricsProto; 59 import com.android.server.wifi.nano.WifiMetricsProto.ConnectToNetworkNotificationAndActionCount; 60 import com.android.server.wifi.nano.WifiMetricsProto.DeviceMobilityStatePnoScanStats; 61 import com.android.server.wifi.nano.WifiMetricsProto.ExperimentValues; 62 import com.android.server.wifi.nano.WifiMetricsProto.LinkProbeStats; 63 import com.android.server.wifi.nano.WifiMetricsProto.LinkProbeStats.ExperimentProbeCounts; 64 import com.android.server.wifi.nano.WifiMetricsProto.LinkProbeStats.LinkProbeFailureReasonCount; 65 import com.android.server.wifi.nano.WifiMetricsProto.LinkSpeedCount; 66 import com.android.server.wifi.nano.WifiMetricsProto.NetworkSelectionExperimentDecisions; 67 import com.android.server.wifi.nano.WifiMetricsProto.PasspointProfileTypeCount; 68 import com.android.server.wifi.nano.WifiMetricsProto.PasspointProvisionStats; 69 import com.android.server.wifi.nano.WifiMetricsProto.PasspointProvisionStats.ProvisionFailureCount; 70 import com.android.server.wifi.nano.WifiMetricsProto.PnoScanMetrics; 71 import com.android.server.wifi.nano.WifiMetricsProto.SoftApConnectedClientsEvent; 72 import com.android.server.wifi.nano.WifiMetricsProto.StaEvent; 73 import com.android.server.wifi.nano.WifiMetricsProto.StaEvent.ConfigInfo; 74 import com.android.server.wifi.nano.WifiMetricsProto.WifiIsUnusableEvent; 75 import com.android.server.wifi.nano.WifiMetricsProto.WifiLinkLayerUsageStats; 76 import com.android.server.wifi.nano.WifiMetricsProto.WifiLockStats; 77 import com.android.server.wifi.nano.WifiMetricsProto.WifiNetworkRequestApiLog; 78 import com.android.server.wifi.nano.WifiMetricsProto.WifiNetworkSuggestionApiLog; 79 import com.android.server.wifi.nano.WifiMetricsProto.WifiToggleStats; 80 import com.android.server.wifi.nano.WifiMetricsProto.WifiUsabilityStats; 81 import com.android.server.wifi.nano.WifiMetricsProto.WifiUsabilityStatsEntry; 82 import com.android.server.wifi.nano.WifiMetricsProto.WpsMetrics; 83 import com.android.server.wifi.p2p.WifiP2pMetrics; 84 import com.android.server.wifi.rtt.RttMetrics; 85 import com.android.server.wifi.util.ExternalCallbackTracker; 86 import com.android.server.wifi.util.InformationElementUtil; 87 import com.android.server.wifi.util.IntCounter; 88 import com.android.server.wifi.util.IntHistogram; 89 import com.android.server.wifi.util.MetricsUtils; 90 import com.android.server.wifi.util.ObjectCounter; 91 import com.android.server.wifi.util.ScanResultUtil; 92 93 import org.json.JSONArray; 94 import org.json.JSONException; 95 import org.json.JSONObject; 96 97 import java.io.FileDescriptor; 98 import java.io.PrintWriter; 99 import java.util.ArrayList; 100 import java.util.BitSet; 101 import java.util.Calendar; 102 import java.util.HashMap; 103 import java.util.HashSet; 104 import java.util.LinkedList; 105 import java.util.List; 106 import java.util.Map; 107 import java.util.Random; 108 import java.util.Set; 109 110 /** 111 * Provides storage for wireless connectivity metrics, as they are generated. 112 * Metrics logged by this class include: 113 * Aggregated connection stats (num of connections, num of failures, ...) 114 * Discrete connection event stats (time, duration, failure codes, ...) 115 * Router details (technology type, authentication type, ...) 116 * Scan stats 117 */ 118 public class WifiMetrics { 119 private static final String TAG = "WifiMetrics"; 120 private static final boolean DBG = false; 121 /** 122 * Clamp the RSSI poll counts to values between [MIN,MAX]_RSSI_POLL 123 */ 124 private static final int MAX_RSSI_POLL = 0; 125 private static final int MIN_RSSI_POLL = -127; 126 public static final int MAX_RSSI_DELTA = 127; 127 public static final int MIN_RSSI_DELTA = -127; 128 /** Minimum link speed (Mbps) to count for link_speed_counts */ 129 public static final int MIN_LINK_SPEED_MBPS = 0; 130 /** Maximum time period between ScanResult and RSSI poll to generate rssi delta datapoint */ 131 public static final long TIMEOUT_RSSI_DELTA_MILLIS = 3000; 132 private static final int MIN_WIFI_SCORE = 0; 133 private static final int MAX_WIFI_SCORE = NetworkAgent.WIFI_BASE_SCORE; 134 private static final int MIN_WIFI_USABILITY_SCORE = 0; // inclusive 135 private static final int MAX_WIFI_USABILITY_SCORE = 100; // inclusive 136 @VisibleForTesting 137 static final int LOW_WIFI_SCORE = 50; // Mobile data score 138 @VisibleForTesting 139 static final int LOW_WIFI_USABILITY_SCORE = 50; // Mobile data score 140 private final Object mLock = new Object(); 141 private static final int MAX_CONNECTION_EVENTS = 256; 142 // Largest bucket in the NumConnectableNetworkCount histogram, 143 // anything large will be stored in this bucket 144 public static final int MAX_CONNECTABLE_SSID_NETWORK_BUCKET = 20; 145 public static final int MAX_CONNECTABLE_BSSID_NETWORK_BUCKET = 50; 146 public static final int MAX_TOTAL_SCAN_RESULT_SSIDS_BUCKET = 100; 147 public static final int MAX_TOTAL_SCAN_RESULTS_BUCKET = 250; 148 public static final int MAX_TOTAL_PASSPOINT_APS_BUCKET = 50; 149 public static final int MAX_TOTAL_PASSPOINT_UNIQUE_ESS_BUCKET = 20; 150 public static final int MAX_PASSPOINT_APS_PER_UNIQUE_ESS_BUCKET = 50; 151 public static final int MAX_TOTAL_80211MC_APS_BUCKET = 20; 152 private static final int CONNECT_TO_NETWORK_NOTIFICATION_ACTION_KEY_MULTIPLIER = 1000; 153 // Max limit for number of soft AP related events, extra events will be dropped. 154 private static final int MAX_NUM_SOFT_AP_EVENTS = 256; 155 // Maximum number of WifiIsUnusableEvent 156 public static final int MAX_UNUSABLE_EVENTS = 20; 157 // Minimum time wait before generating next WifiIsUnusableEvent from data stall 158 public static final int MIN_DATA_STALL_WAIT_MS = 120 * 1000; // 2 minutes 159 private static final int WIFI_IS_UNUSABLE_EVENT_METRICS_ENABLED_DEFAULT = 1; // 1 = true 160 private static final int WIFI_LINK_SPEED_METRICS_ENABLED_DEFAULT = 1; // 1 = true 161 // Max number of WifiUsabilityStatsEntry elements to store in the ringbuffer. 162 public static final int MAX_WIFI_USABILITY_STATS_ENTRIES_LIST_SIZE = 40; 163 // Max number of WifiUsabilityStats elements to store for each type. 164 public static final int MAX_WIFI_USABILITY_STATS_LIST_SIZE_PER_TYPE = 10; 165 // Max number of WifiUsabilityStats per labeled type to upload to server 166 public static final int MAX_WIFI_USABILITY_STATS_PER_TYPE_TO_UPLOAD = 2; 167 public static final int NUM_WIFI_USABILITY_STATS_ENTRIES_PER_WIFI_GOOD = 100; 168 public static final int MIN_WIFI_GOOD_USABILITY_STATS_PERIOD_MS = 1000 * 3600; // 1 hour 169 // Histogram for WifiConfigStore IO duration times. Indicates the following 5 buckets (in ms): 170 // < 50 171 // [50, 100) 172 // [100, 150) 173 // [150, 200) 174 // [200, 300) 175 // >= 300 176 private static final int[] WIFI_CONFIG_STORE_IO_DURATION_BUCKET_RANGES_MS = 177 {50, 100, 150, 200, 300}; 178 // Minimum time wait before generating a LABEL_GOOD stats after score breaching low. 179 public static final int MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS = 60 * 1000; // 1 minute 180 // Maximum time that a score breaching low event stays valid. 181 public static final int VALIDITY_PERIOD_OF_SCORE_BREACH_LOW_MS = 90 * 1000; // 1.5 minutes 182 183 private Clock mClock; 184 private boolean mScreenOn; 185 private int mWifiState; 186 private WifiAwareMetrics mWifiAwareMetrics; 187 private RttMetrics mRttMetrics; 188 private final PnoScanMetrics mPnoScanMetrics = new PnoScanMetrics(); 189 private final WifiLinkLayerUsageStats mWifiLinkLayerUsageStats = new WifiLinkLayerUsageStats(); 190 private final WpsMetrics mWpsMetrics = new WpsMetrics(); 191 private final ExperimentValues mExperimentValues = new ExperimentValues(); 192 private Handler mHandler; 193 private ScoringParams mScoringParams; 194 private WifiConfigManager mWifiConfigManager; 195 private WifiNetworkSelector mWifiNetworkSelector; 196 private PasspointManager mPasspointManager; 197 private Context mContext; 198 private FrameworkFacade mFacade; 199 private WifiDataStall mWifiDataStall; 200 private WifiLinkLayerStats mLastLinkLayerStats; 201 private String mLastBssid; 202 private int mLastFrequency = -1; 203 private int mSeqNumInsideFramework = 0; 204 private int mLastWifiUsabilityScore = -1; 205 private int mLastWifiUsabilityScoreNoReset = -1; 206 private int mLastPredictionHorizonSec = -1; 207 private int mLastPredictionHorizonSecNoReset = -1; 208 private int mSeqNumToFramework = -1; 209 @ProbeStatus private int mProbeStatusSinceLastUpdate = 210 android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE; 211 private int mProbeElapsedTimeSinceLastUpdateMs = -1; 212 private int mProbeMcsRateSinceLastUpdate = -1; 213 private long mScoreBreachLowTimeMillis = -1; 214 215 public static final int MAX_STA_EVENTS = 768; 216 private LinkedList<StaEventWithTime> mStaEventList = new LinkedList<>(); 217 private int mLastPollRssi = -127; 218 private int mLastPollLinkSpeed = -1; 219 private int mLastPollFreq = -1; 220 private int mLastScore = -1; 221 222 /** Tracks if we should be logging WifiIsUnusableEvent */ 223 private boolean mUnusableEventLogging = false; 224 /** Tracks if we should be logging LinkSpeedCounts */ 225 private boolean mLinkSpeedCountsLogging = true; 226 227 /** 228 * Metrics are stored within an instance of the WifiLog proto during runtime, 229 * The ConnectionEvent, SystemStateEntries & ScanReturnEntries metrics are stored during 230 * runtime in member lists of this WifiMetrics class, with the final WifiLog proto being pieced 231 * together at dump-time 232 */ 233 private final WifiMetricsProto.WifiLog mWifiLogProto = new WifiMetricsProto.WifiLog(); 234 /** 235 * Session information that gets logged for every Wifi connection attempt. 236 */ 237 private final List<ConnectionEvent> mConnectionEventList = new ArrayList<>(); 238 /** 239 * The latest started (but un-ended) connection attempt 240 */ 241 private ConnectionEvent mCurrentConnectionEvent; 242 /** 243 * Count of number of times each scan return code, indexed by WifiLog.ScanReturnCode 244 */ 245 private final SparseIntArray mScanReturnEntries = new SparseIntArray(); 246 /** 247 * Mapping of system state to the counts of scans requested in that wifi state * screenOn 248 * combination. Indexed by WifiLog.WifiState * (1 + screenOn) 249 */ 250 private final SparseIntArray mWifiSystemStateEntries = new SparseIntArray(); 251 /** Mapping of channel frequency to its RSSI distribution histogram **/ 252 private final Map<Integer, SparseIntArray> mRssiPollCountsMap = new HashMap<>(); 253 /** Mapping of RSSI scan-poll delta values to counts. */ 254 private final SparseIntArray mRssiDeltaCounts = new SparseIntArray(); 255 /** Mapping of link speed values to LinkSpeedCount objects. */ 256 private final SparseArray<LinkSpeedCount> mLinkSpeedCounts = new SparseArray<>(); 257 /** RSSI of the scan result for the last connection event*/ 258 private int mScanResultRssi = 0; 259 /** Boot-relative timestamp when the last candidate scanresult was received, used to calculate 260 RSSI deltas. -1 designates no candidate scanResult being tracked */ 261 private long mScanResultRssiTimestampMillis = -1; 262 /** Mapping of alert reason to the respective alert count. */ 263 private final SparseIntArray mWifiAlertReasonCounts = new SparseIntArray(); 264 /** 265 * Records the getElapsedSinceBootMillis (in seconds) that represents the beginning of data 266 * capture for for this WifiMetricsProto 267 */ 268 private long mRecordStartTimeSec; 269 /** Mapping of Wifi Scores to counts */ 270 private final SparseIntArray mWifiScoreCounts = new SparseIntArray(); 271 /** Mapping of Wifi Usability Scores to counts */ 272 private final SparseIntArray mWifiUsabilityScoreCounts = new SparseIntArray(); 273 /** Mapping of SoftApManager start SoftAp return codes to counts */ 274 private final SparseIntArray mSoftApManagerReturnCodeCounts = new SparseIntArray(); 275 276 private final SparseIntArray mTotalSsidsInScanHistogram = new SparseIntArray(); 277 private final SparseIntArray mTotalBssidsInScanHistogram = new SparseIntArray(); 278 private final SparseIntArray mAvailableOpenSsidsInScanHistogram = new SparseIntArray(); 279 private final SparseIntArray mAvailableOpenBssidsInScanHistogram = new SparseIntArray(); 280 private final SparseIntArray mAvailableSavedSsidsInScanHistogram = new SparseIntArray(); 281 private final SparseIntArray mAvailableSavedBssidsInScanHistogram = new SparseIntArray(); 282 private final SparseIntArray mAvailableOpenOrSavedSsidsInScanHistogram = new SparseIntArray(); 283 private final SparseIntArray mAvailableOpenOrSavedBssidsInScanHistogram = new SparseIntArray(); 284 private final SparseIntArray mAvailableSavedPasspointProviderProfilesInScanHistogram = 285 new SparseIntArray(); 286 private final SparseIntArray mAvailableSavedPasspointProviderBssidsInScanHistogram = 287 new SparseIntArray(); 288 289 private final IntCounter mInstalledPasspointProfileTypeForR1 = new IntCounter(); 290 private final IntCounter mInstalledPasspointProfileTypeForR2 = new IntCounter(); 291 292 /** Mapping of "Connect to Network" notifications to counts. */ 293 private final SparseIntArray mConnectToNetworkNotificationCount = new SparseIntArray(); 294 /** Mapping of "Connect to Network" notification user actions to counts. */ 295 private final SparseIntArray mConnectToNetworkNotificationActionCount = new SparseIntArray(); 296 private int mOpenNetworkRecommenderBlacklistSize = 0; 297 private boolean mIsWifiNetworksAvailableNotificationOn = false; 298 private int mNumOpenNetworkConnectMessageFailedToSend = 0; 299 private int mNumOpenNetworkRecommendationUpdates = 0; 300 /** List of soft AP events related to number of connected clients in tethered mode */ 301 private final List<SoftApConnectedClientsEvent> mSoftApEventListTethered = new ArrayList<>(); 302 /** List of soft AP events related to number of connected clients in local only mode */ 303 private final List<SoftApConnectedClientsEvent> mSoftApEventListLocalOnly = new ArrayList<>(); 304 305 private final SparseIntArray mObservedHotspotR1ApInScanHistogram = new SparseIntArray(); 306 private final SparseIntArray mObservedHotspotR2ApInScanHistogram = new SparseIntArray(); 307 private final SparseIntArray mObservedHotspotR1EssInScanHistogram = new SparseIntArray(); 308 private final SparseIntArray mObservedHotspotR2EssInScanHistogram = new SparseIntArray(); 309 private final SparseIntArray mObservedHotspotR1ApsPerEssInScanHistogram = new SparseIntArray(); 310 private final SparseIntArray mObservedHotspotR2ApsPerEssInScanHistogram = new SparseIntArray(); 311 312 private final SparseIntArray mObserved80211mcApInScanHistogram = new SparseIntArray(); 313 314 // link probing stats 315 private final IntCounter mLinkProbeSuccessRssiCounts = new IntCounter(-85, -65); 316 private final IntCounter mLinkProbeFailureRssiCounts = new IntCounter(-85, -65); 317 private final IntCounter mLinkProbeSuccessLinkSpeedCounts = new IntCounter(); 318 private final IntCounter mLinkProbeFailureLinkSpeedCounts = new IntCounter(); 319 320 private static final int[] LINK_PROBE_TIME_SINCE_LAST_TX_SUCCESS_SECONDS_HISTOGRAM_BUCKETS = 321 {5, 15, 45, 135}; 322 private final IntHistogram mLinkProbeSuccessSecondsSinceLastTxSuccessHistogram = 323 new IntHistogram(LINK_PROBE_TIME_SINCE_LAST_TX_SUCCESS_SECONDS_HISTOGRAM_BUCKETS); 324 private final IntHistogram mLinkProbeFailureSecondsSinceLastTxSuccessHistogram = 325 new IntHistogram(LINK_PROBE_TIME_SINCE_LAST_TX_SUCCESS_SECONDS_HISTOGRAM_BUCKETS); 326 327 private static final int[] LINK_PROBE_ELAPSED_TIME_MS_HISTOGRAM_BUCKETS = 328 {5, 10, 15, 20, 25, 50, 100, 200, 400, 800}; 329 private final IntHistogram mLinkProbeSuccessElapsedTimeMsHistogram = new IntHistogram( 330 LINK_PROBE_ELAPSED_TIME_MS_HISTOGRAM_BUCKETS); 331 private final IntCounter mLinkProbeFailureReasonCounts = new IntCounter(); 332 333 /** 334 * Maps a String link probe experiment ID to the number of link probes that were sent for this 335 * experiment. 336 */ 337 private final ObjectCounter<String> mLinkProbeExperimentProbeCounts = new ObjectCounter<>(); 338 private int mLinkProbeStaEventCount = 0; 339 @VisibleForTesting static final int MAX_LINK_PROBE_STA_EVENTS = MAX_STA_EVENTS / 4; 340 341 private final LinkedList<WifiUsabilityStatsEntry> mWifiUsabilityStatsEntriesList = 342 new LinkedList<>(); 343 private final LinkedList<WifiUsabilityStats> mWifiUsabilityStatsListBad = new LinkedList<>(); 344 private final LinkedList<WifiUsabilityStats> mWifiUsabilityStatsListGood = new LinkedList<>(); 345 private int mWifiUsabilityStatsCounter = 0; 346 private final Random mRand = new Random(); 347 private final ExternalCallbackTracker<IOnWifiUsabilityStatsListener> mOnWifiUsabilityListeners; 348 349 private final SparseArray<DeviceMobilityStatePnoScanStats> mMobilityStatePnoStatsMap = 350 new SparseArray<>(); 351 private int mCurrentDeviceMobilityState; 352 /** 353 * The timestamp of the start of the current device mobility state. 354 */ 355 private long mCurrentDeviceMobilityStateStartMs; 356 /** 357 * The timestamp of when the PNO scan started in the current device mobility state. 358 */ 359 private long mCurrentDeviceMobilityStatePnoScanStartMs; 360 361 /** Wifi power metrics*/ 362 private WifiPowerMetrics mWifiPowerMetrics; 363 364 /** Wifi Wake metrics */ 365 private final WifiWakeMetrics mWifiWakeMetrics = new WifiWakeMetrics(); 366 367 /** Wifi P2p metrics */ 368 private final WifiP2pMetrics mWifiP2pMetrics; 369 370 private boolean mIsMacRandomizationOn = false; 371 372 /** DPP */ 373 private final DppMetrics mDppMetrics; 374 375 /** WifiConfigStore read duration histogram. */ 376 private SparseIntArray mWifiConfigStoreReadDurationHistogram = new SparseIntArray(); 377 378 /** WifiConfigStore write duration histogram. */ 379 private SparseIntArray mWifiConfigStoreWriteDurationHistogram = new SparseIntArray(); 380 381 /** New API surface metrics */ 382 private final WifiNetworkRequestApiLog mWifiNetworkRequestApiLog = 383 new WifiNetworkRequestApiLog(); 384 private static final int[] NETWORK_REQUEST_API_MATCH_SIZE_HISTOGRAM_BUCKETS = 385 {0, 1, 5, 10}; 386 private final IntHistogram mWifiNetworkRequestApiMatchSizeHistogram = 387 new IntHistogram(NETWORK_REQUEST_API_MATCH_SIZE_HISTOGRAM_BUCKETS); 388 389 private final WifiNetworkSuggestionApiLog mWifiNetworkSuggestionApiLog = 390 new WifiNetworkSuggestionApiLog(); 391 private static final int[] NETWORK_SUGGESTION_API_LIST_SIZE_HISTOGRAM_BUCKETS = 392 {5, 20, 50, 100, 500}; 393 private final IntHistogram mWifiNetworkSuggestionApiListSizeHistogram = 394 new IntHistogram(NETWORK_SUGGESTION_API_LIST_SIZE_HISTOGRAM_BUCKETS); 395 private final WifiLockStats mWifiLockStats = new WifiLockStats(); 396 private static final int[] WIFI_LOCK_SESSION_DURATION_HISTOGRAM_BUCKETS = 397 {1, 10, 60, 600, 3600}; 398 private final WifiToggleStats mWifiToggleStats = new WifiToggleStats(); 399 400 private final IntHistogram mWifiLockHighPerfAcqDurationSecHistogram = 401 new IntHistogram(WIFI_LOCK_SESSION_DURATION_HISTOGRAM_BUCKETS); 402 private final IntHistogram mWifiLockLowLatencyAcqDurationSecHistogram = 403 new IntHistogram(WIFI_LOCK_SESSION_DURATION_HISTOGRAM_BUCKETS); 404 405 private final IntHistogram mWifiLockHighPerfActiveSessionDurationSecHistogram = 406 new IntHistogram(WIFI_LOCK_SESSION_DURATION_HISTOGRAM_BUCKETS); 407 private final IntHistogram mWifiLockLowLatencyActiveSessionDurationSecHistogram = 408 new IntHistogram(WIFI_LOCK_SESSION_DURATION_HISTOGRAM_BUCKETS); 409 410 /** 411 * (experiment1Id, experiment2Id) => 412 * (sameSelectionNumChoicesCounter, differentSelectionNumChoicesCounter) 413 */ 414 private Map<Pair<Integer, Integer>, NetworkSelectionExperimentResults> 415 mNetworkSelectionExperimentPairNumChoicesCounts = new ArrayMap<>(); 416 417 private int mNetworkSelectorExperimentId; 418 419 private final CellularLinkLayerStatsCollector mCellularLinkLayerStatsCollector; 420 421 /** 422 * Tracks the nominator for each network (i.e. which entity made the suggestion to connect). 423 * This object should not be cleared. 424 */ 425 private final SparseIntArray mNetworkIdToNominatorId = new SparseIntArray(); 426 427 /** passpoint provision success count */ 428 private int mNumProvisionSuccess = 0; 429 430 /** Mapping of failure code to the respective passpoint provision failure count. */ 431 private final IntCounter mPasspointProvisionFailureCounts = new IntCounter(); 432 433 @VisibleForTesting 434 static class NetworkSelectionExperimentResults { 435 public static final int MAX_CHOICES = 10; 436 437 public IntCounter sameSelectionNumChoicesCounter = new IntCounter(0, MAX_CHOICES); 438 public IntCounter differentSelectionNumChoicesCounter = new IntCounter(0, MAX_CHOICES); 439 440 @Override toString()441 public String toString() { 442 return "NetworkSelectionExperimentResults{" 443 + "sameSelectionNumChoicesCounter=" 444 + sameSelectionNumChoicesCounter 445 + ", differentSelectionNumChoicesCounter=" 446 + differentSelectionNumChoicesCounter 447 + '}'; 448 } 449 } 450 451 class RouterFingerPrint { 452 private WifiMetricsProto.RouterFingerPrint mRouterFingerPrintProto; RouterFingerPrint()453 RouterFingerPrint() { 454 mRouterFingerPrintProto = new WifiMetricsProto.RouterFingerPrint(); 455 } 456 toString()457 public String toString() { 458 StringBuilder sb = new StringBuilder(); 459 synchronized (mLock) { 460 sb.append("mConnectionEvent.roamType=" + mRouterFingerPrintProto.roamType); 461 sb.append(", mChannelInfo=" + mRouterFingerPrintProto.channelInfo); 462 sb.append(", mDtim=" + mRouterFingerPrintProto.dtim); 463 sb.append(", mAuthentication=" + mRouterFingerPrintProto.authentication); 464 sb.append(", mHidden=" + mRouterFingerPrintProto.hidden); 465 sb.append(", mRouterTechnology=" + mRouterFingerPrintProto.routerTechnology); 466 sb.append(", mSupportsIpv6=" + mRouterFingerPrintProto.supportsIpv6); 467 } 468 return sb.toString(); 469 } updateFromWifiConfiguration(WifiConfiguration config)470 public void updateFromWifiConfiguration(WifiConfiguration config) { 471 synchronized (mLock) { 472 if (config != null) { 473 // Is this a hidden network 474 mRouterFingerPrintProto.hidden = config.hiddenSSID; 475 // Config may not have a valid dtimInterval set yet, in which case dtim will be zero 476 // (These are only populated from beacon frame scan results, which are returned as 477 // scan results from the chip far less frequently than Probe-responses) 478 if (config.dtimInterval > 0) { 479 mRouterFingerPrintProto.dtim = config.dtimInterval; 480 } 481 mCurrentConnectionEvent.mConfigSsid = config.SSID; 482 // Get AuthType information from config (We do this again from ScanResult after 483 // associating with BSSID) 484 if (config.allowedKeyManagement != null 485 && config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) { 486 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto 487 .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_OPEN; 488 } else if (config.isEnterprise()) { 489 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto 490 .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE; 491 } else { 492 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto 493 .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL; 494 } 495 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto 496 .passpoint = config.isPasspoint(); 497 // If there's a ScanResult candidate associated with this config already, get it and 498 // log (more accurate) metrics from it 499 ScanResult candidate = config.getNetworkSelectionStatus().getCandidate(); 500 if (candidate != null) { 501 updateMetricsFromScanResult(candidate); 502 } 503 } 504 } 505 } 506 } 507 508 /** 509 * Log event, tracking the start time, end time and result of a wireless connection attempt. 510 */ 511 class ConnectionEvent { 512 WifiMetricsProto.ConnectionEvent mConnectionEvent; 513 //<TODO> Move these constants into a wifi.proto Enum, and create a new Failure Type field 514 //covering more than just l2 failures. see b/27652362 515 /** 516 * Failure codes, used for the 'level_2_failure_code' Connection event field (covers a lot 517 * more failures than just l2 though, since the proto does not have a place to log 518 * framework failures) 519 */ 520 // Failure is unknown 521 public static final int FAILURE_UNKNOWN = 0; 522 // NONE 523 public static final int FAILURE_NONE = 1; 524 // ASSOCIATION_REJECTION_EVENT 525 public static final int FAILURE_ASSOCIATION_REJECTION = 2; 526 // AUTHENTICATION_FAILURE_EVENT 527 public static final int FAILURE_AUTHENTICATION_FAILURE = 3; 528 // SSID_TEMP_DISABLED (Also Auth failure) 529 public static final int FAILURE_SSID_TEMP_DISABLED = 4; 530 // reconnect() or reassociate() call to WifiNative failed 531 public static final int FAILURE_CONNECT_NETWORK_FAILED = 5; 532 // NETWORK_DISCONNECTION_EVENT 533 public static final int FAILURE_NETWORK_DISCONNECTION = 6; 534 // NEW_CONNECTION_ATTEMPT before previous finished 535 public static final int FAILURE_NEW_CONNECTION_ATTEMPT = 7; 536 // New connection attempt to the same network & bssid 537 public static final int FAILURE_REDUNDANT_CONNECTION_ATTEMPT = 8; 538 // Roam Watchdog timer triggered (Roaming timed out) 539 public static final int FAILURE_ROAM_TIMEOUT = 9; 540 // DHCP failure 541 public static final int FAILURE_DHCP = 10; 542 // ASSOCIATION_TIMED_OUT 543 public static final int FAILURE_ASSOCIATION_TIMED_OUT = 11; 544 545 RouterFingerPrint mRouterFingerPrint; 546 private long mRealStartTime; 547 private long mRealEndTime; 548 private String mConfigSsid; 549 private String mConfigBssid; 550 private int mWifiState; 551 private boolean mScreenOn; 552 ConnectionEvent()553 private ConnectionEvent() { 554 mConnectionEvent = new WifiMetricsProto.ConnectionEvent(); 555 mRealEndTime = 0; 556 mRealStartTime = 0; 557 mRouterFingerPrint = new RouterFingerPrint(); 558 mConnectionEvent.routerFingerprint = mRouterFingerPrint.mRouterFingerPrintProto; 559 mConfigSsid = "<NULL>"; 560 mConfigBssid = "<NULL>"; 561 mWifiState = WifiMetricsProto.WifiLog.WIFI_UNKNOWN; 562 mScreenOn = false; 563 } 564 toString()565 public String toString() { 566 StringBuilder sb = new StringBuilder(); 567 sb.append("startTime="); 568 Calendar c = Calendar.getInstance(); 569 synchronized (mLock) { 570 c.setTimeInMillis(mConnectionEvent.startTimeMillis); 571 sb.append(mConnectionEvent.startTimeMillis == 0 ? " <null>" : 572 String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)); 573 sb.append(", SSID="); 574 sb.append(mConfigSsid); 575 sb.append(", BSSID="); 576 sb.append(mConfigBssid); 577 sb.append(", durationMillis="); 578 sb.append(mConnectionEvent.durationTakenToConnectMillis); 579 sb.append(", roamType="); 580 switch(mConnectionEvent.roamType) { 581 case 1: 582 sb.append("ROAM_NONE"); 583 break; 584 case 2: 585 sb.append("ROAM_DBDC"); 586 break; 587 case 3: 588 sb.append("ROAM_ENTERPRISE"); 589 break; 590 case 4: 591 sb.append("ROAM_USER_SELECTED"); 592 break; 593 case 5: 594 sb.append("ROAM_UNRELATED"); 595 break; 596 default: 597 sb.append("ROAM_UNKNOWN"); 598 } 599 sb.append(", connectionResult="); 600 sb.append(mConnectionEvent.connectionResult); 601 sb.append(", level2FailureCode="); 602 switch(mConnectionEvent.level2FailureCode) { 603 case FAILURE_NONE: 604 sb.append("NONE"); 605 break; 606 case FAILURE_ASSOCIATION_REJECTION: 607 sb.append("ASSOCIATION_REJECTION"); 608 break; 609 case FAILURE_AUTHENTICATION_FAILURE: 610 sb.append("AUTHENTICATION_FAILURE"); 611 break; 612 case FAILURE_SSID_TEMP_DISABLED: 613 sb.append("SSID_TEMP_DISABLED"); 614 break; 615 case FAILURE_CONNECT_NETWORK_FAILED: 616 sb.append("CONNECT_NETWORK_FAILED"); 617 break; 618 case FAILURE_NETWORK_DISCONNECTION: 619 sb.append("NETWORK_DISCONNECTION"); 620 break; 621 case FAILURE_NEW_CONNECTION_ATTEMPT: 622 sb.append("NEW_CONNECTION_ATTEMPT"); 623 break; 624 case FAILURE_REDUNDANT_CONNECTION_ATTEMPT: 625 sb.append("REDUNDANT_CONNECTION_ATTEMPT"); 626 break; 627 case FAILURE_ROAM_TIMEOUT: 628 sb.append("ROAM_TIMEOUT"); 629 break; 630 case FAILURE_DHCP: 631 sb.append("DHCP"); 632 break; 633 case FAILURE_ASSOCIATION_TIMED_OUT: 634 sb.append("ASSOCIATION_TIMED_OUT"); 635 break; 636 default: 637 sb.append("UNKNOWN"); 638 break; 639 } 640 sb.append(", connectivityLevelFailureCode="); 641 switch(mConnectionEvent.connectivityLevelFailureCode) { 642 case WifiMetricsProto.ConnectionEvent.HLF_NONE: 643 sb.append("NONE"); 644 break; 645 case WifiMetricsProto.ConnectionEvent.HLF_DHCP: 646 sb.append("DHCP"); 647 break; 648 case WifiMetricsProto.ConnectionEvent.HLF_NO_INTERNET: 649 sb.append("NO_INTERNET"); 650 break; 651 case WifiMetricsProto.ConnectionEvent.HLF_UNWANTED: 652 sb.append("UNWANTED"); 653 break; 654 default: 655 sb.append("UNKNOWN"); 656 break; 657 } 658 sb.append(", signalStrength="); 659 sb.append(mConnectionEvent.signalStrength); 660 sb.append(", wifiState="); 661 switch(mWifiState) { 662 case WifiMetricsProto.WifiLog.WIFI_DISABLED: 663 sb.append("WIFI_DISABLED"); 664 break; 665 case WifiMetricsProto.WifiLog.WIFI_DISCONNECTED: 666 sb.append("WIFI_DISCONNECTED"); 667 break; 668 case WifiMetricsProto.WifiLog.WIFI_ASSOCIATED: 669 sb.append("WIFI_ASSOCIATED"); 670 break; 671 default: 672 sb.append("WIFI_UNKNOWN"); 673 break; 674 } 675 sb.append(", screenOn="); 676 sb.append(mScreenOn); 677 sb.append(", mRouterFingerprint="); 678 sb.append(mRouterFingerPrint.toString()); 679 sb.append(", useRandomizedMac="); 680 sb.append(mConnectionEvent.useRandomizedMac); 681 sb.append(", connectionNominator="); 682 switch (mConnectionEvent.connectionNominator) { 683 case WifiMetricsProto.ConnectionEvent.NOMINATOR_UNKNOWN: 684 sb.append("NOMINATOR_UNKNOWN"); 685 break; 686 case WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL: 687 sb.append("NOMINATOR_MANUAL"); 688 break; 689 case WifiMetricsProto.ConnectionEvent.NOMINATOR_SAVED: 690 sb.append("NOMINATOR_SAVED"); 691 break; 692 case WifiMetricsProto.ConnectionEvent.NOMINATOR_SUGGESTION: 693 sb.append("NOMINATOR_SUGGESTION"); 694 break; 695 case WifiMetricsProto.ConnectionEvent.NOMINATOR_PASSPOINT: 696 sb.append("NOMINATOR_PASSPOINT"); 697 break; 698 case WifiMetricsProto.ConnectionEvent.NOMINATOR_CARRIER: 699 sb.append("NOMINATOR_CARRIER"); 700 break; 701 case WifiMetricsProto.ConnectionEvent.NOMINATOR_EXTERNAL_SCORED: 702 sb.append("NOMINATOR_EXTERNAL_SCORED"); 703 break; 704 case WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER: 705 sb.append("NOMINATOR_SPECIFIER"); 706 break; 707 case WifiMetricsProto.ConnectionEvent.NOMINATOR_SAVED_USER_CONNECT_CHOICE: 708 sb.append("NOMINATOR_SAVED_USER_CONNECT_CHOICE"); 709 break; 710 case WifiMetricsProto.ConnectionEvent.NOMINATOR_OPEN_NETWORK_AVAILABLE: 711 sb.append("NOMINATOR_OPEN_NETWORK_AVAILABLE"); 712 break; 713 default: 714 sb.append(String.format("UnrecognizedNominator(%d)", 715 mConnectionEvent.connectionNominator)); 716 } 717 sb.append(", networkSelectorExperimentId="); 718 sb.append(mConnectionEvent.networkSelectorExperimentId); 719 sb.append(", level2FailureReason="); 720 switch(mConnectionEvent.level2FailureReason) { 721 case WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_NONE: 722 sb.append("AUTH_FAILURE_NONE"); 723 break; 724 case WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_TIMEOUT: 725 sb.append("AUTH_FAILURE_TIMEOUT"); 726 break; 727 case WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_WRONG_PSWD: 728 sb.append("AUTH_FAILURE_WRONG_PSWD"); 729 break; 730 case WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_EAP_FAILURE: 731 sb.append("AUTH_FAILURE_EAP_FAILURE"); 732 break; 733 default: 734 sb.append("FAILURE_REASON_UNKNOWN"); 735 break; 736 } 737 } 738 return sb.toString(); 739 } 740 } 741 WifiMetrics(Context context, FrameworkFacade facade, Clock clock, Looper looper, WifiAwareMetrics awareMetrics, RttMetrics rttMetrics, WifiPowerMetrics wifiPowerMetrics, WifiP2pMetrics wifiP2pMetrics, DppMetrics dppMetrics, CellularLinkLayerStatsCollector cellularLinkLayerStatsCollector)742 public WifiMetrics(Context context, FrameworkFacade facade, Clock clock, Looper looper, 743 WifiAwareMetrics awareMetrics, RttMetrics rttMetrics, 744 WifiPowerMetrics wifiPowerMetrics, WifiP2pMetrics wifiP2pMetrics, 745 DppMetrics dppMetrics, 746 CellularLinkLayerStatsCollector cellularLinkLayerStatsCollector) { 747 mContext = context; 748 mFacade = facade; 749 mClock = clock; 750 mCurrentConnectionEvent = null; 751 mScreenOn = true; 752 mWifiState = WifiMetricsProto.WifiLog.WIFI_DISABLED; 753 mRecordStartTimeSec = mClock.getElapsedSinceBootMillis() / 1000; 754 mWifiAwareMetrics = awareMetrics; 755 mRttMetrics = rttMetrics; 756 mWifiPowerMetrics = wifiPowerMetrics; 757 mWifiP2pMetrics = wifiP2pMetrics; 758 mDppMetrics = dppMetrics; 759 mCellularLinkLayerStatsCollector = cellularLinkLayerStatsCollector; 760 loadSettings(); 761 mHandler = new Handler(looper) { 762 public void handleMessage(Message msg) { 763 synchronized (mLock) { 764 processMessage(msg); 765 } 766 } 767 }; 768 769 mCurrentDeviceMobilityState = WifiManager.DEVICE_MOBILITY_STATE_UNKNOWN; 770 DeviceMobilityStatePnoScanStats unknownStateStats = 771 getOrCreateDeviceMobilityStatePnoScanStats(mCurrentDeviceMobilityState); 772 unknownStateStats.numTimesEnteredState++; 773 mCurrentDeviceMobilityStateStartMs = mClock.getElapsedSinceBootMillis(); 774 mCurrentDeviceMobilityStatePnoScanStartMs = -1; 775 mOnWifiUsabilityListeners = 776 new ExternalCallbackTracker<IOnWifiUsabilityStatsListener>(mHandler); 777 } 778 779 /** 780 * Load setting values related to metrics logging. 781 */ 782 @VisibleForTesting loadSettings()783 public void loadSettings() { 784 int unusableEventFlag = mFacade.getIntegerSetting( 785 mContext, Settings.Global.WIFI_IS_UNUSABLE_EVENT_METRICS_ENABLED, 786 WIFI_IS_UNUSABLE_EVENT_METRICS_ENABLED_DEFAULT); 787 mUnusableEventLogging = (unusableEventFlag == 1); 788 setWifiIsUnusableLoggingEnabled(mUnusableEventLogging); 789 int linkSpeedCountsFlag = mFacade.getIntegerSetting( 790 mContext, Settings.Global.WIFI_LINK_SPEED_METRICS_ENABLED, 791 WIFI_LINK_SPEED_METRICS_ENABLED_DEFAULT); 792 mLinkSpeedCountsLogging = (linkSpeedCountsFlag == 1); 793 setLinkSpeedCountsLoggingEnabled(mLinkSpeedCountsLogging); 794 if (mWifiDataStall != null) { 795 mWifiDataStall.loadSettings(); 796 } 797 } 798 799 /** Sets internal ScoringParams member */ setScoringParams(ScoringParams scoringParams)800 public void setScoringParams(ScoringParams scoringParams) { 801 mScoringParams = scoringParams; 802 } 803 804 /** Sets internal WifiConfigManager member */ setWifiConfigManager(WifiConfigManager wifiConfigManager)805 public void setWifiConfigManager(WifiConfigManager wifiConfigManager) { 806 mWifiConfigManager = wifiConfigManager; 807 } 808 809 /** Sets internal WifiNetworkSelector member */ setWifiNetworkSelector(WifiNetworkSelector wifiNetworkSelector)810 public void setWifiNetworkSelector(WifiNetworkSelector wifiNetworkSelector) { 811 mWifiNetworkSelector = wifiNetworkSelector; 812 } 813 814 /** Sets internal PasspointManager member */ setPasspointManager(PasspointManager passpointManager)815 public void setPasspointManager(PasspointManager passpointManager) { 816 mPasspointManager = passpointManager; 817 } 818 819 /** Sets internal WifiDataStall member */ setWifiDataStall(WifiDataStall wifiDataStall)820 public void setWifiDataStall(WifiDataStall wifiDataStall) { 821 mWifiDataStall = wifiDataStall; 822 } 823 824 /** 825 * Increment cumulative counters for link layer stats. 826 * @param newStats 827 */ incrementWifiLinkLayerUsageStats(WifiLinkLayerStats newStats)828 public void incrementWifiLinkLayerUsageStats(WifiLinkLayerStats newStats) { 829 if (newStats == null) { 830 return; 831 } 832 if (mLastLinkLayerStats == null) { 833 mLastLinkLayerStats = newStats; 834 return; 835 } 836 if (!newLinkLayerStatsIsValid(mLastLinkLayerStats, newStats)) { 837 // This could mean the radio chip is reset or the data is incorrectly reported. 838 // Don't increment any counts and discard the possibly corrupt |newStats| completely. 839 mLastLinkLayerStats = null; 840 return; 841 } 842 mWifiLinkLayerUsageStats.loggingDurationMs += 843 (newStats.timeStampInMs - mLastLinkLayerStats.timeStampInMs); 844 mWifiLinkLayerUsageStats.radioOnTimeMs += (newStats.on_time - mLastLinkLayerStats.on_time); 845 mWifiLinkLayerUsageStats.radioTxTimeMs += (newStats.tx_time - mLastLinkLayerStats.tx_time); 846 mWifiLinkLayerUsageStats.radioRxTimeMs += (newStats.rx_time - mLastLinkLayerStats.rx_time); 847 mWifiLinkLayerUsageStats.radioScanTimeMs += 848 (newStats.on_time_scan - mLastLinkLayerStats.on_time_scan); 849 mWifiLinkLayerUsageStats.radioNanScanTimeMs += 850 (newStats.on_time_nan_scan - mLastLinkLayerStats.on_time_nan_scan); 851 mWifiLinkLayerUsageStats.radioBackgroundScanTimeMs += 852 (newStats.on_time_background_scan - mLastLinkLayerStats.on_time_background_scan); 853 mWifiLinkLayerUsageStats.radioRoamScanTimeMs += 854 (newStats.on_time_roam_scan - mLastLinkLayerStats.on_time_roam_scan); 855 mWifiLinkLayerUsageStats.radioPnoScanTimeMs += 856 (newStats.on_time_pno_scan - mLastLinkLayerStats.on_time_pno_scan); 857 mWifiLinkLayerUsageStats.radioHs20ScanTimeMs += 858 (newStats.on_time_hs20_scan - mLastLinkLayerStats.on_time_hs20_scan); 859 mLastLinkLayerStats = newStats; 860 } 861 newLinkLayerStatsIsValid(WifiLinkLayerStats oldStats, WifiLinkLayerStats newStats)862 private boolean newLinkLayerStatsIsValid(WifiLinkLayerStats oldStats, 863 WifiLinkLayerStats newStats) { 864 if (newStats.on_time < oldStats.on_time 865 || newStats.tx_time < oldStats.tx_time 866 || newStats.rx_time < oldStats.rx_time 867 || newStats.on_time_scan < oldStats.on_time_scan) { 868 return false; 869 } 870 return true; 871 } 872 873 /** 874 * Increment total number of attempts to start a pno scan 875 */ incrementPnoScanStartAttempCount()876 public void incrementPnoScanStartAttempCount() { 877 synchronized (mLock) { 878 mPnoScanMetrics.numPnoScanAttempts++; 879 } 880 } 881 882 /** 883 * Increment total number of attempts with pno scan failed 884 */ incrementPnoScanFailedCount()885 public void incrementPnoScanFailedCount() { 886 synchronized (mLock) { 887 mPnoScanMetrics.numPnoScanFailed++; 888 } 889 } 890 891 /** 892 * Increment number of pno scans started successfully over offload 893 */ incrementPnoScanStartedOverOffloadCount()894 public void incrementPnoScanStartedOverOffloadCount() { 895 synchronized (mLock) { 896 mPnoScanMetrics.numPnoScanStartedOverOffload++; 897 } 898 } 899 900 /** 901 * Increment number of pno scans failed over offload 902 */ incrementPnoScanFailedOverOffloadCount()903 public void incrementPnoScanFailedOverOffloadCount() { 904 synchronized (mLock) { 905 mPnoScanMetrics.numPnoScanFailedOverOffload++; 906 } 907 } 908 909 /** 910 * Increment number of times pno scan found a result 911 */ incrementPnoFoundNetworkEventCount()912 public void incrementPnoFoundNetworkEventCount() { 913 synchronized (mLock) { 914 mPnoScanMetrics.numPnoFoundNetworkEvents++; 915 } 916 } 917 918 /** 919 * Increment total number of wps connection attempts 920 */ incrementWpsAttemptCount()921 public void incrementWpsAttemptCount() { 922 synchronized (mLock) { 923 mWpsMetrics.numWpsAttempts++; 924 } 925 } 926 927 /** 928 * Increment total number of wps connection success 929 */ incrementWpsSuccessCount()930 public void incrementWpsSuccessCount() { 931 synchronized (mLock) { 932 mWpsMetrics.numWpsSuccess++; 933 } 934 } 935 936 /** 937 * Increment total number of wps failure on start 938 */ incrementWpsStartFailureCount()939 public void incrementWpsStartFailureCount() { 940 synchronized (mLock) { 941 mWpsMetrics.numWpsStartFailure++; 942 } 943 } 944 945 /** 946 * Increment total number of wps overlap failure 947 */ incrementWpsOverlapFailureCount()948 public void incrementWpsOverlapFailureCount() { 949 synchronized (mLock) { 950 mWpsMetrics.numWpsOverlapFailure++; 951 } 952 } 953 954 /** 955 * Increment total number of wps timeout failure 956 */ incrementWpsTimeoutFailureCount()957 public void incrementWpsTimeoutFailureCount() { 958 synchronized (mLock) { 959 mWpsMetrics.numWpsTimeoutFailure++; 960 } 961 } 962 963 /** 964 * Increment total number of other wps failure during connection 965 */ incrementWpsOtherConnectionFailureCount()966 public void incrementWpsOtherConnectionFailureCount() { 967 synchronized (mLock) { 968 mWpsMetrics.numWpsOtherConnectionFailure++; 969 } 970 } 971 972 /** 973 * Increment total number of supplicant failure after wps 974 */ incrementWpsSupplicantFailureCount()975 public void incrementWpsSupplicantFailureCount() { 976 synchronized (mLock) { 977 mWpsMetrics.numWpsSupplicantFailure++; 978 } 979 } 980 981 /** 982 * Increment total number of wps cancellation 983 */ incrementWpsCancellationCount()984 public void incrementWpsCancellationCount() { 985 synchronized (mLock) { 986 mWpsMetrics.numWpsCancellation++; 987 } 988 } 989 990 // Values used for indexing SystemStateEntries 991 private static final int SCREEN_ON = 1; 992 private static final int SCREEN_OFF = 0; 993 994 /** 995 * Create a new connection event. Call when wifi attempts to make a new network connection 996 * If there is a current 'un-ended' connection event, it will be ended with UNKNOWN connectivity 997 * failure code. 998 * Gathers and sets the RouterFingerPrint data as well 999 * 1000 * @param config WifiConfiguration of the config used for the current connection attempt 1001 * @param roamType Roam type that caused connection attempt, see WifiMetricsProto.WifiLog.ROAM_X 1002 */ startConnectionEvent(WifiConfiguration config, String targetBSSID, int roamType)1003 public void startConnectionEvent(WifiConfiguration config, String targetBSSID, int roamType) { 1004 synchronized (mLock) { 1005 // Check if this is overlapping another current connection event 1006 if (mCurrentConnectionEvent != null) { 1007 //Is this new Connection Event the same as the current one 1008 if (mCurrentConnectionEvent.mConfigSsid != null 1009 && mCurrentConnectionEvent.mConfigBssid != null 1010 && config != null 1011 && mCurrentConnectionEvent.mConfigSsid.equals(config.SSID) 1012 && (mCurrentConnectionEvent.mConfigBssid.equals("any") 1013 || mCurrentConnectionEvent.mConfigBssid.equals(targetBSSID))) { 1014 mCurrentConnectionEvent.mConfigBssid = targetBSSID; 1015 // End Connection Event due to new connection attempt to the same network 1016 endConnectionEvent(ConnectionEvent.FAILURE_REDUNDANT_CONNECTION_ATTEMPT, 1017 WifiMetricsProto.ConnectionEvent.HLF_NONE, 1018 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN); 1019 } else { 1020 // End Connection Event due to new connection attempt to different network 1021 endConnectionEvent(ConnectionEvent.FAILURE_NEW_CONNECTION_ATTEMPT, 1022 WifiMetricsProto.ConnectionEvent.HLF_NONE, 1023 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN); 1024 } 1025 } 1026 //If past maximum connection events, start removing the oldest 1027 while(mConnectionEventList.size() >= MAX_CONNECTION_EVENTS) { 1028 mConnectionEventList.remove(0); 1029 } 1030 mCurrentConnectionEvent = new ConnectionEvent(); 1031 mCurrentConnectionEvent.mConnectionEvent.startTimeMillis = 1032 mClock.getWallClockMillis(); 1033 mCurrentConnectionEvent.mConfigBssid = targetBSSID; 1034 mCurrentConnectionEvent.mConnectionEvent.roamType = roamType; 1035 mCurrentConnectionEvent.mConnectionEvent.networkSelectorExperimentId = 1036 mNetworkSelectorExperimentId; 1037 mCurrentConnectionEvent.mRouterFingerPrint.updateFromWifiConfiguration(config); 1038 mCurrentConnectionEvent.mConfigBssid = "any"; 1039 mCurrentConnectionEvent.mRealStartTime = mClock.getElapsedSinceBootMillis(); 1040 mCurrentConnectionEvent.mWifiState = mWifiState; 1041 mCurrentConnectionEvent.mScreenOn = mScreenOn; 1042 mConnectionEventList.add(mCurrentConnectionEvent); 1043 mScanResultRssiTimestampMillis = -1; 1044 if (config != null) { 1045 mCurrentConnectionEvent.mConnectionEvent.useRandomizedMac = 1046 config.macRandomizationSetting 1047 == WifiConfiguration.RANDOMIZATION_PERSISTENT; 1048 mCurrentConnectionEvent.mConnectionEvent.connectionNominator = 1049 mNetworkIdToNominatorId.get(config.networkId, 1050 WifiMetricsProto.ConnectionEvent.NOMINATOR_UNKNOWN); 1051 ScanResult candidate = config.getNetworkSelectionStatus().getCandidate(); 1052 if (candidate != null) { 1053 // Cache the RSSI of the candidate, as the connection event level is updated 1054 // from other sources (polls, bssid_associations) and delta requires the 1055 // scanResult rssi 1056 mScanResultRssi = candidate.level; 1057 mScanResultRssiTimestampMillis = mClock.getElapsedSinceBootMillis(); 1058 } 1059 } 1060 } 1061 } 1062 1063 /** 1064 * set the RoamType of the current ConnectionEvent (if any) 1065 */ setConnectionEventRoamType(int roamType)1066 public void setConnectionEventRoamType(int roamType) { 1067 synchronized (mLock) { 1068 if (mCurrentConnectionEvent != null) { 1069 mCurrentConnectionEvent.mConnectionEvent.roamType = roamType; 1070 } 1071 } 1072 } 1073 1074 /** 1075 * Set AP related metrics from ScanDetail 1076 */ setConnectionScanDetail(ScanDetail scanDetail)1077 public void setConnectionScanDetail(ScanDetail scanDetail) { 1078 synchronized (mLock) { 1079 if (mCurrentConnectionEvent != null && scanDetail != null) { 1080 NetworkDetail networkDetail = scanDetail.getNetworkDetail(); 1081 ScanResult scanResult = scanDetail.getScanResult(); 1082 //Ensure that we have a networkDetail, and that it corresponds to the currently 1083 //tracked connection attempt 1084 if (networkDetail != null && scanResult != null 1085 && mCurrentConnectionEvent.mConfigSsid != null 1086 && mCurrentConnectionEvent.mConfigSsid 1087 .equals("\"" + networkDetail.getSSID() + "\"")) { 1088 updateMetricsFromNetworkDetail(networkDetail); 1089 updateMetricsFromScanResult(scanResult); 1090 } 1091 } 1092 } 1093 } 1094 1095 /** 1096 * End a Connection event record. Call when wifi connection attempt succeeds or fails. 1097 * If a Connection event has not been started and is active when .end is called, a new one is 1098 * created with zero duration. 1099 * 1100 * @param level2FailureCode Level 2 failure code returned by supplicant 1101 * @param connectivityFailureCode WifiMetricsProto.ConnectionEvent.HLF_X 1102 * @param level2FailureReason Breakdown of level2FailureCode with more detailed reason 1103 */ endConnectionEvent(int level2FailureCode, int connectivityFailureCode, int level2FailureReason)1104 public void endConnectionEvent(int level2FailureCode, int connectivityFailureCode, 1105 int level2FailureReason) { 1106 synchronized (mLock) { 1107 if (mCurrentConnectionEvent != null) { 1108 boolean result = (level2FailureCode == 1) 1109 && (connectivityFailureCode == WifiMetricsProto.ConnectionEvent.HLF_NONE); 1110 mCurrentConnectionEvent.mConnectionEvent.connectionResult = result ? 1 : 0; 1111 mCurrentConnectionEvent.mRealEndTime = mClock.getElapsedSinceBootMillis(); 1112 mCurrentConnectionEvent.mConnectionEvent.durationTakenToConnectMillis = (int) 1113 (mCurrentConnectionEvent.mRealEndTime 1114 - mCurrentConnectionEvent.mRealStartTime); 1115 mCurrentConnectionEvent.mConnectionEvent.level2FailureCode = level2FailureCode; 1116 mCurrentConnectionEvent.mConnectionEvent.connectivityLevelFailureCode = 1117 connectivityFailureCode; 1118 mCurrentConnectionEvent.mConnectionEvent.level2FailureReason = level2FailureReason; 1119 // ConnectionEvent already added to ConnectionEvents List. Safe to null current here 1120 mCurrentConnectionEvent = null; 1121 if (!result) { 1122 mScanResultRssiTimestampMillis = -1; 1123 } 1124 } 1125 } 1126 } 1127 1128 /** 1129 * Set ConnectionEvent DTIM Interval (if set), and 802.11 Connection mode, from NetworkDetail 1130 */ updateMetricsFromNetworkDetail(NetworkDetail networkDetail)1131 private void updateMetricsFromNetworkDetail(NetworkDetail networkDetail) { 1132 int dtimInterval = networkDetail.getDtimInterval(); 1133 if (dtimInterval > 0) { 1134 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.dtim = 1135 dtimInterval; 1136 } 1137 int connectionWifiMode; 1138 switch (networkDetail.getWifiMode()) { 1139 case InformationElementUtil.WifiMode.MODE_UNDEFINED: 1140 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_UNKNOWN; 1141 break; 1142 case InformationElementUtil.WifiMode.MODE_11A: 1143 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_A; 1144 break; 1145 case InformationElementUtil.WifiMode.MODE_11B: 1146 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_B; 1147 break; 1148 case InformationElementUtil.WifiMode.MODE_11G: 1149 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_G; 1150 break; 1151 case InformationElementUtil.WifiMode.MODE_11N: 1152 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_N; 1153 break; 1154 case InformationElementUtil.WifiMode.MODE_11AC : 1155 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_AC; 1156 break; 1157 default: 1158 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_OTHER; 1159 break; 1160 } 1161 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto 1162 .routerTechnology = connectionWifiMode; 1163 } 1164 1165 /** 1166 * Set ConnectionEvent RSSI and authentication type from ScanResult 1167 */ updateMetricsFromScanResult(ScanResult scanResult)1168 private void updateMetricsFromScanResult(ScanResult scanResult) { 1169 mCurrentConnectionEvent.mConnectionEvent.signalStrength = scanResult.level; 1170 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication = 1171 WifiMetricsProto.RouterFingerPrint.AUTH_OPEN; 1172 mCurrentConnectionEvent.mConfigBssid = scanResult.BSSID; 1173 if (scanResult.capabilities != null) { 1174 if (ScanResultUtil.isScanResultForWepNetwork(scanResult)) { 1175 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication = 1176 WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL; 1177 } else if (ScanResultUtil.isScanResultForPskNetwork(scanResult) 1178 || ScanResultUtil.isScanResultForSaeNetwork(scanResult)) { 1179 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication = 1180 WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL; 1181 } else if (ScanResultUtil.isScanResultForEapNetwork(scanResult) 1182 || ScanResultUtil.isScanResultForEapSuiteBNetwork(scanResult)) { 1183 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication = 1184 WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE; 1185 } 1186 } 1187 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.channelInfo = 1188 scanResult.frequency; 1189 } 1190 setIsLocationEnabled(boolean enabled)1191 void setIsLocationEnabled(boolean enabled) { 1192 synchronized (mLock) { 1193 mWifiLogProto.isLocationEnabled = enabled; 1194 } 1195 } 1196 setIsScanningAlwaysEnabled(boolean enabled)1197 void setIsScanningAlwaysEnabled(boolean enabled) { 1198 synchronized (mLock) { 1199 mWifiLogProto.isScanningAlwaysEnabled = enabled; 1200 } 1201 } 1202 1203 /** 1204 * Increment Non Empty Scan Results count 1205 */ incrementNonEmptyScanResultCount()1206 public void incrementNonEmptyScanResultCount() { 1207 if (DBG) Log.v(TAG, "incrementNonEmptyScanResultCount"); 1208 synchronized (mLock) { 1209 mWifiLogProto.numNonEmptyScanResults++; 1210 } 1211 } 1212 1213 /** 1214 * Increment Empty Scan Results count 1215 */ incrementEmptyScanResultCount()1216 public void incrementEmptyScanResultCount() { 1217 if (DBG) Log.v(TAG, "incrementEmptyScanResultCount"); 1218 synchronized (mLock) { 1219 mWifiLogProto.numEmptyScanResults++; 1220 } 1221 } 1222 1223 /** 1224 * Increment background scan count 1225 */ incrementBackgroundScanCount()1226 public void incrementBackgroundScanCount() { 1227 if (DBG) Log.v(TAG, "incrementBackgroundScanCount"); 1228 synchronized (mLock) { 1229 mWifiLogProto.numBackgroundScans++; 1230 } 1231 } 1232 1233 /** 1234 * Get Background scan count 1235 */ getBackgroundScanCount()1236 public int getBackgroundScanCount() { 1237 synchronized (mLock) { 1238 return mWifiLogProto.numBackgroundScans; 1239 } 1240 } 1241 1242 /** 1243 * Increment oneshot scan count, and the associated WifiSystemScanStateCount entry 1244 */ incrementOneshotScanCount()1245 public void incrementOneshotScanCount() { 1246 synchronized (mLock) { 1247 mWifiLogProto.numOneshotScans++; 1248 } 1249 incrementWifiSystemScanStateCount(mWifiState, mScreenOn); 1250 } 1251 1252 /** 1253 * Increment the count of oneshot scans that include DFS channels. 1254 */ incrementOneshotScanWithDfsCount()1255 public void incrementOneshotScanWithDfsCount() { 1256 synchronized (mLock) { 1257 mWifiLogProto.numOneshotHasDfsChannelScans++; 1258 } 1259 } 1260 1261 /** 1262 * Increment connectivity oneshot scan count. 1263 */ incrementConnectivityOneshotScanCount()1264 public void incrementConnectivityOneshotScanCount() { 1265 synchronized (mLock) { 1266 mWifiLogProto.numConnectivityOneshotScans++; 1267 } 1268 } 1269 1270 /** 1271 * Get oneshot scan count 1272 */ getOneshotScanCount()1273 public int getOneshotScanCount() { 1274 synchronized (mLock) { 1275 return mWifiLogProto.numOneshotScans; 1276 } 1277 } 1278 1279 /** 1280 * Get connectivity oneshot scan count 1281 */ getConnectivityOneshotScanCount()1282 public int getConnectivityOneshotScanCount() { 1283 synchronized (mLock) { 1284 return mWifiLogProto.numConnectivityOneshotScans; 1285 } 1286 } 1287 1288 /** 1289 * Get the count of oneshot scan requests that included DFS channels. 1290 */ getOneshotScanWithDfsCount()1291 public int getOneshotScanWithDfsCount() { 1292 synchronized (mLock) { 1293 return mWifiLogProto.numOneshotHasDfsChannelScans; 1294 } 1295 } 1296 1297 /** 1298 * Increment oneshot scan count for external apps. 1299 */ incrementExternalAppOneshotScanRequestsCount()1300 public void incrementExternalAppOneshotScanRequestsCount() { 1301 synchronized (mLock) { 1302 mWifiLogProto.numExternalAppOneshotScanRequests++; 1303 } 1304 } 1305 /** 1306 * Increment oneshot scan throttle count for external foreground apps. 1307 */ incrementExternalForegroundAppOneshotScanRequestsThrottledCount()1308 public void incrementExternalForegroundAppOneshotScanRequestsThrottledCount() { 1309 synchronized (mLock) { 1310 mWifiLogProto.numExternalForegroundAppOneshotScanRequestsThrottled++; 1311 } 1312 } 1313 1314 /** 1315 * Increment oneshot scan throttle count for external background apps. 1316 */ incrementExternalBackgroundAppOneshotScanRequestsThrottledCount()1317 public void incrementExternalBackgroundAppOneshotScanRequestsThrottledCount() { 1318 synchronized (mLock) { 1319 mWifiLogProto.numExternalBackgroundAppOneshotScanRequestsThrottled++; 1320 } 1321 } 1322 returnCodeToString(int scanReturnCode)1323 private String returnCodeToString(int scanReturnCode) { 1324 switch(scanReturnCode){ 1325 case WifiMetricsProto.WifiLog.SCAN_UNKNOWN: 1326 return "SCAN_UNKNOWN"; 1327 case WifiMetricsProto.WifiLog.SCAN_SUCCESS: 1328 return "SCAN_SUCCESS"; 1329 case WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED: 1330 return "SCAN_FAILURE_INTERRUPTED"; 1331 case WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION: 1332 return "SCAN_FAILURE_INVALID_CONFIGURATION"; 1333 case WifiMetricsProto.WifiLog.FAILURE_WIFI_DISABLED: 1334 return "FAILURE_WIFI_DISABLED"; 1335 default: 1336 return "<UNKNOWN>"; 1337 } 1338 } 1339 1340 /** 1341 * Increment count of scan return code occurrence 1342 * 1343 * @param scanReturnCode Return code from scan attempt WifiMetricsProto.WifiLog.SCAN_X 1344 */ incrementScanReturnEntry(int scanReturnCode, int countToAdd)1345 public void incrementScanReturnEntry(int scanReturnCode, int countToAdd) { 1346 synchronized (mLock) { 1347 if (DBG) Log.v(TAG, "incrementScanReturnEntry " + returnCodeToString(scanReturnCode)); 1348 int entry = mScanReturnEntries.get(scanReturnCode); 1349 entry += countToAdd; 1350 mScanReturnEntries.put(scanReturnCode, entry); 1351 } 1352 } 1353 /** 1354 * Get the count of this scanReturnCode 1355 * @param scanReturnCode that we are getting the count for 1356 */ getScanReturnEntry(int scanReturnCode)1357 public int getScanReturnEntry(int scanReturnCode) { 1358 synchronized (mLock) { 1359 return mScanReturnEntries.get(scanReturnCode); 1360 } 1361 } 1362 wifiSystemStateToString(int state)1363 private String wifiSystemStateToString(int state) { 1364 switch(state){ 1365 case WifiMetricsProto.WifiLog.WIFI_UNKNOWN: 1366 return "WIFI_UNKNOWN"; 1367 case WifiMetricsProto.WifiLog.WIFI_DISABLED: 1368 return "WIFI_DISABLED"; 1369 case WifiMetricsProto.WifiLog.WIFI_DISCONNECTED: 1370 return "WIFI_DISCONNECTED"; 1371 case WifiMetricsProto.WifiLog.WIFI_ASSOCIATED: 1372 return "WIFI_ASSOCIATED"; 1373 default: 1374 return "default"; 1375 } 1376 } 1377 1378 /** 1379 * Increments the count of scans initiated by each wifi state, accounts for screenOn/Off 1380 * 1381 * @param state State of the system when scan was initiated, see WifiMetricsProto.WifiLog.WIFI_X 1382 * @param screenOn Is the screen on 1383 */ incrementWifiSystemScanStateCount(int state, boolean screenOn)1384 public void incrementWifiSystemScanStateCount(int state, boolean screenOn) { 1385 synchronized (mLock) { 1386 if (DBG) { 1387 Log.v(TAG, "incrementWifiSystemScanStateCount " + wifiSystemStateToString(state) 1388 + " " + screenOn); 1389 } 1390 int index = (state * 2) + (screenOn ? SCREEN_ON : SCREEN_OFF); 1391 int entry = mWifiSystemStateEntries.get(index); 1392 entry++; 1393 mWifiSystemStateEntries.put(index, entry); 1394 } 1395 } 1396 1397 /** 1398 * Get the count of this system State Entry 1399 */ getSystemStateCount(int state, boolean screenOn)1400 public int getSystemStateCount(int state, boolean screenOn) { 1401 synchronized (mLock) { 1402 int index = state * 2 + (screenOn ? SCREEN_ON : SCREEN_OFF); 1403 return mWifiSystemStateEntries.get(index); 1404 } 1405 } 1406 1407 /** 1408 * Increment number of times the Watchdog of Last Resort triggered, resetting the wifi stack 1409 */ incrementNumLastResortWatchdogTriggers()1410 public void incrementNumLastResortWatchdogTriggers() { 1411 synchronized (mLock) { 1412 mWifiLogProto.numLastResortWatchdogTriggers++; 1413 } 1414 } 1415 /** 1416 * @param count number of networks over bad association threshold when watchdog triggered 1417 */ addCountToNumLastResortWatchdogBadAssociationNetworksTotal(int count)1418 public void addCountToNumLastResortWatchdogBadAssociationNetworksTotal(int count) { 1419 synchronized (mLock) { 1420 mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal += count; 1421 } 1422 } 1423 /** 1424 * @param count number of networks over bad authentication threshold when watchdog triggered 1425 */ addCountToNumLastResortWatchdogBadAuthenticationNetworksTotal(int count)1426 public void addCountToNumLastResortWatchdogBadAuthenticationNetworksTotal(int count) { 1427 synchronized (mLock) { 1428 mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal += count; 1429 } 1430 } 1431 /** 1432 * @param count number of networks over bad dhcp threshold when watchdog triggered 1433 */ addCountToNumLastResortWatchdogBadDhcpNetworksTotal(int count)1434 public void addCountToNumLastResortWatchdogBadDhcpNetworksTotal(int count) { 1435 synchronized (mLock) { 1436 mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal += count; 1437 } 1438 } 1439 /** 1440 * @param count number of networks over bad other threshold when watchdog triggered 1441 */ addCountToNumLastResortWatchdogBadOtherNetworksTotal(int count)1442 public void addCountToNumLastResortWatchdogBadOtherNetworksTotal(int count) { 1443 synchronized (mLock) { 1444 mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal += count; 1445 } 1446 } 1447 /** 1448 * @param count number of networks seen when watchdog triggered 1449 */ addCountToNumLastResortWatchdogAvailableNetworksTotal(int count)1450 public void addCountToNumLastResortWatchdogAvailableNetworksTotal(int count) { 1451 synchronized (mLock) { 1452 mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal += count; 1453 } 1454 } 1455 /** 1456 * Increment count of triggers with atleast one bad association network 1457 */ incrementNumLastResortWatchdogTriggersWithBadAssociation()1458 public void incrementNumLastResortWatchdogTriggersWithBadAssociation() { 1459 synchronized (mLock) { 1460 mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation++; 1461 } 1462 } 1463 /** 1464 * Increment count of triggers with atleast one bad authentication network 1465 */ incrementNumLastResortWatchdogTriggersWithBadAuthentication()1466 public void incrementNumLastResortWatchdogTriggersWithBadAuthentication() { 1467 synchronized (mLock) { 1468 mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication++; 1469 } 1470 } 1471 /** 1472 * Increment count of triggers with atleast one bad dhcp network 1473 */ incrementNumLastResortWatchdogTriggersWithBadDhcp()1474 public void incrementNumLastResortWatchdogTriggersWithBadDhcp() { 1475 synchronized (mLock) { 1476 mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp++; 1477 } 1478 } 1479 /** 1480 * Increment count of triggers with atleast one bad other network 1481 */ incrementNumLastResortWatchdogTriggersWithBadOther()1482 public void incrementNumLastResortWatchdogTriggersWithBadOther() { 1483 synchronized (mLock) { 1484 mWifiLogProto.numLastResortWatchdogTriggersWithBadOther++; 1485 } 1486 } 1487 1488 /** 1489 * Increment number of times connectivity watchdog confirmed pno is working 1490 */ incrementNumConnectivityWatchdogPnoGood()1491 public void incrementNumConnectivityWatchdogPnoGood() { 1492 synchronized (mLock) { 1493 mWifiLogProto.numConnectivityWatchdogPnoGood++; 1494 } 1495 } 1496 /** 1497 * Increment number of times connectivity watchdog found pno not working 1498 */ incrementNumConnectivityWatchdogPnoBad()1499 public void incrementNumConnectivityWatchdogPnoBad() { 1500 synchronized (mLock) { 1501 mWifiLogProto.numConnectivityWatchdogPnoBad++; 1502 } 1503 } 1504 /** 1505 * Increment number of times connectivity watchdog confirmed background scan is working 1506 */ incrementNumConnectivityWatchdogBackgroundGood()1507 public void incrementNumConnectivityWatchdogBackgroundGood() { 1508 synchronized (mLock) { 1509 mWifiLogProto.numConnectivityWatchdogBackgroundGood++; 1510 } 1511 } 1512 /** 1513 * Increment number of times connectivity watchdog found background scan not working 1514 */ incrementNumConnectivityWatchdogBackgroundBad()1515 public void incrementNumConnectivityWatchdogBackgroundBad() { 1516 synchronized (mLock) { 1517 mWifiLogProto.numConnectivityWatchdogBackgroundBad++; 1518 } 1519 } 1520 1521 /** 1522 * Increment various poll related metrics, and cache performance data for StaEvent logging 1523 */ handlePollResult(WifiInfo wifiInfo)1524 public void handlePollResult(WifiInfo wifiInfo) { 1525 mLastPollRssi = wifiInfo.getRssi(); 1526 mLastPollLinkSpeed = wifiInfo.getLinkSpeed(); 1527 mLastPollFreq = wifiInfo.getFrequency(); 1528 incrementRssiPollRssiCount(mLastPollFreq, mLastPollRssi); 1529 incrementLinkSpeedCount(mLastPollLinkSpeed, mLastPollRssi); 1530 } 1531 1532 /** 1533 * Increment occurence count of RSSI level from RSSI poll for the given frequency. 1534 * @param frequency (MHz) 1535 * @param rssi 1536 */ 1537 @VisibleForTesting incrementRssiPollRssiCount(int frequency, int rssi)1538 public void incrementRssiPollRssiCount(int frequency, int rssi) { 1539 if (!(rssi >= MIN_RSSI_POLL && rssi <= MAX_RSSI_POLL)) { 1540 return; 1541 } 1542 synchronized (mLock) { 1543 if (!mRssiPollCountsMap.containsKey(frequency)) { 1544 mRssiPollCountsMap.put(frequency, new SparseIntArray()); 1545 } 1546 SparseIntArray sparseIntArray = mRssiPollCountsMap.get(frequency); 1547 int count = sparseIntArray.get(rssi); 1548 sparseIntArray.put(rssi, count + 1); 1549 maybeIncrementRssiDeltaCount(rssi - mScanResultRssi); 1550 } 1551 } 1552 1553 /** 1554 * Increment occurence count of difference between scan result RSSI and the first RSSI poll. 1555 * Ignores rssi values outside the bounds of [MIN_RSSI_DELTA, MAX_RSSI_DELTA] 1556 * mLock must be held when calling this method. 1557 */ maybeIncrementRssiDeltaCount(int rssi)1558 private void maybeIncrementRssiDeltaCount(int rssi) { 1559 // Check if this RSSI poll is close enough to a scan result RSSI to log a delta value 1560 if (mScanResultRssiTimestampMillis >= 0) { 1561 long timeDelta = mClock.getElapsedSinceBootMillis() - mScanResultRssiTimestampMillis; 1562 if (timeDelta <= TIMEOUT_RSSI_DELTA_MILLIS) { 1563 if (rssi >= MIN_RSSI_DELTA && rssi <= MAX_RSSI_DELTA) { 1564 int count = mRssiDeltaCounts.get(rssi); 1565 mRssiDeltaCounts.put(rssi, count + 1); 1566 } 1567 } 1568 mScanResultRssiTimestampMillis = -1; 1569 } 1570 } 1571 1572 /** 1573 * Increment occurrence count of link speed. 1574 * Ignores link speed values that are lower than MIN_LINK_SPEED_MBPS 1575 * and rssi values outside the bounds of [MIN_RSSI_POLL, MAX_RSSI_POLL] 1576 */ 1577 @VisibleForTesting incrementLinkSpeedCount(int linkSpeed, int rssi)1578 public void incrementLinkSpeedCount(int linkSpeed, int rssi) { 1579 if (!(mLinkSpeedCountsLogging 1580 && linkSpeed >= MIN_LINK_SPEED_MBPS 1581 && rssi >= MIN_RSSI_POLL 1582 && rssi <= MAX_RSSI_POLL)) { 1583 return; 1584 } 1585 synchronized (mLock) { 1586 LinkSpeedCount linkSpeedCount = mLinkSpeedCounts.get(linkSpeed); 1587 if (linkSpeedCount == null) { 1588 linkSpeedCount = new LinkSpeedCount(); 1589 linkSpeedCount.linkSpeedMbps = linkSpeed; 1590 mLinkSpeedCounts.put(linkSpeed, linkSpeedCount); 1591 } 1592 linkSpeedCount.count++; 1593 linkSpeedCount.rssiSumDbm += Math.abs(rssi); 1594 linkSpeedCount.rssiSumOfSquaresDbmSq += rssi * rssi; 1595 } 1596 } 1597 1598 /** 1599 * Increment count of Watchdog successes. 1600 */ incrementNumLastResortWatchdogSuccesses()1601 public void incrementNumLastResortWatchdogSuccesses() { 1602 synchronized (mLock) { 1603 mWifiLogProto.numLastResortWatchdogSuccesses++; 1604 } 1605 } 1606 1607 /** 1608 * Increment the count of network connection failures that happened after watchdog has been 1609 * triggered. 1610 */ incrementWatchdogTotalConnectionFailureCountAfterTrigger()1611 public void incrementWatchdogTotalConnectionFailureCountAfterTrigger() { 1612 synchronized (mLock) { 1613 mWifiLogProto.watchdogTotalConnectionFailureCountAfterTrigger++; 1614 } 1615 } 1616 1617 /** 1618 * Sets the time taken for wifi to connect after a watchdog triggers a restart. 1619 * @param milliseconds 1620 */ setWatchdogSuccessTimeDurationMs(long ms)1621 public void setWatchdogSuccessTimeDurationMs(long ms) { 1622 synchronized (mLock) { 1623 mWifiLogProto.watchdogTriggerToConnectionSuccessDurationMs = ms; 1624 } 1625 } 1626 1627 /** 1628 * Increments the count of alerts by alert reason. 1629 * 1630 * @param reason The cause of the alert. The reason values are driver-specific. 1631 */ incrementAlertReasonCount(int reason)1632 private void incrementAlertReasonCount(int reason) { 1633 if (reason > WifiLoggerHal.WIFI_ALERT_REASON_MAX 1634 || reason < WifiLoggerHal.WIFI_ALERT_REASON_MIN) { 1635 reason = WifiLoggerHal.WIFI_ALERT_REASON_RESERVED; 1636 } 1637 synchronized (mLock) { 1638 int alertCount = mWifiAlertReasonCounts.get(reason); 1639 mWifiAlertReasonCounts.put(reason, alertCount + 1); 1640 } 1641 } 1642 1643 /** 1644 * Counts all the different types of networks seen in a set of scan results 1645 */ countScanResults(List<ScanDetail> scanDetails)1646 public void countScanResults(List<ScanDetail> scanDetails) { 1647 if (scanDetails == null) { 1648 return; 1649 } 1650 int totalResults = 0; 1651 int openNetworks = 0; 1652 int personalNetworks = 0; 1653 int enterpriseNetworks = 0; 1654 int hiddenNetworks = 0; 1655 int hotspot2r1Networks = 0; 1656 int hotspot2r2Networks = 0; 1657 int enhacedOpenNetworks = 0; 1658 int wpa3PersonalNetworks = 0; 1659 int wpa3EnterpriseNetworks = 0; 1660 1661 for (ScanDetail scanDetail : scanDetails) { 1662 NetworkDetail networkDetail = scanDetail.getNetworkDetail(); 1663 ScanResult scanResult = scanDetail.getScanResult(); 1664 totalResults++; 1665 if (networkDetail != null) { 1666 if (networkDetail.isHiddenBeaconFrame()) { 1667 hiddenNetworks++; 1668 } 1669 if (networkDetail.getHSRelease() != null) { 1670 if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R1) { 1671 hotspot2r1Networks++; 1672 } else if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R2) { 1673 hotspot2r2Networks++; 1674 } 1675 } 1676 } 1677 if (scanResult != null && scanResult.capabilities != null) { 1678 if (ScanResultUtil.isScanResultForEapSuiteBNetwork(scanResult)) { 1679 wpa3EnterpriseNetworks++; 1680 } else if (ScanResultUtil.isScanResultForEapNetwork(scanResult)) { 1681 enterpriseNetworks++; 1682 } else if (ScanResultUtil.isScanResultForSaeNetwork(scanResult)) { 1683 wpa3PersonalNetworks++; 1684 } else if (ScanResultUtil.isScanResultForPskNetwork(scanResult) 1685 || ScanResultUtil.isScanResultForWepNetwork(scanResult)) { 1686 personalNetworks++; 1687 } else if (ScanResultUtil.isScanResultForOweNetwork(scanResult)) { 1688 enhacedOpenNetworks++; 1689 } else { 1690 openNetworks++; 1691 } 1692 } 1693 } 1694 synchronized (mLock) { 1695 mWifiLogProto.numTotalScanResults += totalResults; 1696 mWifiLogProto.numOpenNetworkScanResults += openNetworks; 1697 mWifiLogProto.numLegacyPersonalNetworkScanResults += personalNetworks; 1698 mWifiLogProto.numLegacyEnterpriseNetworkScanResults += enterpriseNetworks; 1699 mWifiLogProto.numEnhancedOpenNetworkScanResults += enhacedOpenNetworks; 1700 mWifiLogProto.numWpa3PersonalNetworkScanResults += wpa3PersonalNetworks; 1701 mWifiLogProto.numWpa3EnterpriseNetworkScanResults += wpa3EnterpriseNetworks; 1702 mWifiLogProto.numHiddenNetworkScanResults += hiddenNetworks; 1703 mWifiLogProto.numHotspot2R1NetworkScanResults += hotspot2r1Networks; 1704 mWifiLogProto.numHotspot2R2NetworkScanResults += hotspot2r2Networks; 1705 mWifiLogProto.numScans++; 1706 } 1707 } 1708 1709 private boolean mWifiWins = false; // Based on scores, use wifi instead of mobile data? 1710 // Based on Wifi usability scores. use wifi instead of mobile data? 1711 private boolean mWifiWinsUsabilityScore = false; 1712 1713 /** 1714 * Increments occurence of a particular wifi score calculated 1715 * in WifiScoreReport by current connected network. Scores are bounded 1716 * within [MIN_WIFI_SCORE, MAX_WIFI_SCORE] to limit size of SparseArray. 1717 * 1718 * Also records events when the current score breaches significant thresholds. 1719 */ incrementWifiScoreCount(int score)1720 public void incrementWifiScoreCount(int score) { 1721 if (score < MIN_WIFI_SCORE || score > MAX_WIFI_SCORE) { 1722 return; 1723 } 1724 synchronized (mLock) { 1725 int count = mWifiScoreCounts.get(score); 1726 mWifiScoreCounts.put(score, count + 1); 1727 1728 boolean wifiWins = mWifiWins; 1729 if (mWifiWins && score < LOW_WIFI_SCORE) { 1730 wifiWins = false; 1731 } else if (!mWifiWins && score > LOW_WIFI_SCORE) { 1732 wifiWins = true; 1733 } 1734 mLastScore = score; 1735 mLastScoreNoReset = score; 1736 if (wifiWins != mWifiWins) { 1737 mWifiWins = wifiWins; 1738 StaEvent event = new StaEvent(); 1739 event.type = StaEvent.TYPE_SCORE_BREACH; 1740 addStaEvent(event); 1741 // Only record the first score breach by checking whether mScoreBreachLowTimeMillis 1742 // has been set to -1 1743 if (!wifiWins && mScoreBreachLowTimeMillis == -1) { 1744 mScoreBreachLowTimeMillis = mClock.getElapsedSinceBootMillis(); 1745 } 1746 } 1747 } 1748 } 1749 1750 /** 1751 * Increments occurence of the results from attempting to start SoftAp. 1752 * Maps the |result| and WifiManager |failureCode| constant to proto defined SoftApStartResult 1753 * codes. 1754 */ incrementSoftApStartResult(boolean result, int failureCode)1755 public void incrementSoftApStartResult(boolean result, int failureCode) { 1756 synchronized (mLock) { 1757 if (result) { 1758 int count = mSoftApManagerReturnCodeCounts.get( 1759 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_STARTED_SUCCESSFULLY); 1760 mSoftApManagerReturnCodeCounts.put( 1761 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_STARTED_SUCCESSFULLY, 1762 count + 1); 1763 return; 1764 } 1765 1766 // now increment failure modes - if not explicitly handled, dump into the general 1767 // error bucket. 1768 if (failureCode == WifiManager.SAP_START_FAILURE_NO_CHANNEL) { 1769 int count = mSoftApManagerReturnCodeCounts.get( 1770 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_NO_CHANNEL); 1771 mSoftApManagerReturnCodeCounts.put( 1772 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_NO_CHANNEL, 1773 count + 1); 1774 } else { 1775 // failure mode not tracked at this time... count as a general error for now. 1776 int count = mSoftApManagerReturnCodeCounts.get( 1777 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_GENERAL_ERROR); 1778 mSoftApManagerReturnCodeCounts.put( 1779 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_GENERAL_ERROR, 1780 count + 1); 1781 } 1782 } 1783 } 1784 1785 /** 1786 * Adds a record indicating the current up state of soft AP 1787 */ addSoftApUpChangedEvent(boolean isUp, int mode)1788 public void addSoftApUpChangedEvent(boolean isUp, int mode) { 1789 SoftApConnectedClientsEvent event = new SoftApConnectedClientsEvent(); 1790 event.eventType = isUp ? SoftApConnectedClientsEvent.SOFT_AP_UP : 1791 SoftApConnectedClientsEvent.SOFT_AP_DOWN; 1792 event.numConnectedClients = 0; 1793 addSoftApConnectedClientsEvent(event, mode); 1794 } 1795 1796 /** 1797 * Adds a record for current number of associated stations to soft AP 1798 */ addSoftApNumAssociatedStationsChangedEvent(int numStations, int mode)1799 public void addSoftApNumAssociatedStationsChangedEvent(int numStations, int mode) { 1800 SoftApConnectedClientsEvent event = new SoftApConnectedClientsEvent(); 1801 event.eventType = SoftApConnectedClientsEvent.NUM_CLIENTS_CHANGED; 1802 event.numConnectedClients = numStations; 1803 addSoftApConnectedClientsEvent(event, mode); 1804 } 1805 1806 /** 1807 * Adds a record to the corresponding event list based on mode param 1808 */ addSoftApConnectedClientsEvent(SoftApConnectedClientsEvent event, int mode)1809 private void addSoftApConnectedClientsEvent(SoftApConnectedClientsEvent event, int mode) { 1810 synchronized (mLock) { 1811 List<SoftApConnectedClientsEvent> softApEventList; 1812 switch (mode) { 1813 case WifiManager.IFACE_IP_MODE_TETHERED: 1814 softApEventList = mSoftApEventListTethered; 1815 break; 1816 case WifiManager.IFACE_IP_MODE_LOCAL_ONLY: 1817 softApEventList = mSoftApEventListLocalOnly; 1818 break; 1819 default: 1820 return; 1821 } 1822 1823 if (softApEventList.size() > MAX_NUM_SOFT_AP_EVENTS) { 1824 return; 1825 } 1826 1827 event.timeStampMillis = mClock.getElapsedSinceBootMillis(); 1828 softApEventList.add(event); 1829 } 1830 } 1831 1832 /** 1833 * Updates current soft AP events with channel info 1834 */ addSoftApChannelSwitchedEvent(int frequency, int bandwidth, int mode)1835 public void addSoftApChannelSwitchedEvent(int frequency, int bandwidth, int mode) { 1836 synchronized (mLock) { 1837 List<SoftApConnectedClientsEvent> softApEventList; 1838 switch (mode) { 1839 case WifiManager.IFACE_IP_MODE_TETHERED: 1840 softApEventList = mSoftApEventListTethered; 1841 break; 1842 case WifiManager.IFACE_IP_MODE_LOCAL_ONLY: 1843 softApEventList = mSoftApEventListLocalOnly; 1844 break; 1845 default: 1846 return; 1847 } 1848 1849 for (int index = softApEventList.size() - 1; index >= 0; index--) { 1850 SoftApConnectedClientsEvent event = softApEventList.get(index); 1851 1852 if (event != null && event.eventType == SoftApConnectedClientsEvent.SOFT_AP_UP) { 1853 event.channelFrequency = frequency; 1854 event.channelBandwidth = bandwidth; 1855 break; 1856 } 1857 } 1858 } 1859 } 1860 1861 /** 1862 * Increment number of times the HAL crashed. 1863 */ incrementNumHalCrashes()1864 public void incrementNumHalCrashes() { 1865 synchronized (mLock) { 1866 mWifiLogProto.numHalCrashes++; 1867 } 1868 } 1869 1870 /** 1871 * Increment number of times the Wificond crashed. 1872 */ incrementNumWificondCrashes()1873 public void incrementNumWificondCrashes() { 1874 synchronized (mLock) { 1875 mWifiLogProto.numWificondCrashes++; 1876 } 1877 } 1878 1879 /** 1880 * Increment number of times the supplicant crashed. 1881 */ incrementNumSupplicantCrashes()1882 public void incrementNumSupplicantCrashes() { 1883 synchronized (mLock) { 1884 mWifiLogProto.numSupplicantCrashes++; 1885 } 1886 } 1887 1888 /** 1889 * Increment number of times the hostapd crashed. 1890 */ incrementNumHostapdCrashes()1891 public void incrementNumHostapdCrashes() { 1892 synchronized (mLock) { 1893 mWifiLogProto.numHostapdCrashes++; 1894 } 1895 } 1896 1897 /** 1898 * Increment number of times the wifi on failed due to an error in HAL. 1899 */ incrementNumSetupClientInterfaceFailureDueToHal()1900 public void incrementNumSetupClientInterfaceFailureDueToHal() { 1901 synchronized (mLock) { 1902 mWifiLogProto.numSetupClientInterfaceFailureDueToHal++; 1903 } 1904 } 1905 1906 /** 1907 * Increment number of times the wifi on failed due to an error in wificond. 1908 */ incrementNumSetupClientInterfaceFailureDueToWificond()1909 public void incrementNumSetupClientInterfaceFailureDueToWificond() { 1910 synchronized (mLock) { 1911 mWifiLogProto.numSetupClientInterfaceFailureDueToWificond++; 1912 } 1913 } 1914 1915 /** 1916 * Increment number of times the wifi on failed due to an error in supplicant. 1917 */ incrementNumSetupClientInterfaceFailureDueToSupplicant()1918 public void incrementNumSetupClientInterfaceFailureDueToSupplicant() { 1919 synchronized (mLock) { 1920 mWifiLogProto.numSetupClientInterfaceFailureDueToSupplicant++; 1921 } 1922 } 1923 1924 /** 1925 * Increment number of times the SoftAp on failed due to an error in HAL. 1926 */ incrementNumSetupSoftApInterfaceFailureDueToHal()1927 public void incrementNumSetupSoftApInterfaceFailureDueToHal() { 1928 synchronized (mLock) { 1929 mWifiLogProto.numSetupSoftApInterfaceFailureDueToHal++; 1930 } 1931 } 1932 1933 /** 1934 * Increment number of times the SoftAp on failed due to an error in wificond. 1935 */ incrementNumSetupSoftApInterfaceFailureDueToWificond()1936 public void incrementNumSetupSoftApInterfaceFailureDueToWificond() { 1937 synchronized (mLock) { 1938 mWifiLogProto.numSetupSoftApInterfaceFailureDueToWificond++; 1939 } 1940 } 1941 1942 /** 1943 * Increment number of times the SoftAp on failed due to an error in hostapd. 1944 */ incrementNumSetupSoftApInterfaceFailureDueToHostapd()1945 public void incrementNumSetupSoftApInterfaceFailureDueToHostapd() { 1946 synchronized (mLock) { 1947 mWifiLogProto.numSetupSoftApInterfaceFailureDueToHostapd++; 1948 } 1949 } 1950 1951 /** 1952 * Increment number of times we got client interface down. 1953 */ incrementNumClientInterfaceDown()1954 public void incrementNumClientInterfaceDown() { 1955 synchronized (mLock) { 1956 mWifiLogProto.numClientInterfaceDown++; 1957 } 1958 } 1959 1960 /** 1961 * Increment number of times we got client interface down. 1962 */ incrementNumSoftApInterfaceDown()1963 public void incrementNumSoftApInterfaceDown() { 1964 synchronized (mLock) { 1965 mWifiLogProto.numSoftApInterfaceDown++; 1966 } 1967 } 1968 1969 /** 1970 * Increment number of times Passpoint provider being installed. 1971 */ incrementNumPasspointProviderInstallation()1972 public void incrementNumPasspointProviderInstallation() { 1973 synchronized (mLock) { 1974 mWifiLogProto.numPasspointProviderInstallation++; 1975 } 1976 } 1977 1978 /** 1979 * Increment number of times Passpoint provider is installed successfully. 1980 */ incrementNumPasspointProviderInstallSuccess()1981 public void incrementNumPasspointProviderInstallSuccess() { 1982 synchronized (mLock) { 1983 mWifiLogProto.numPasspointProviderInstallSuccess++; 1984 } 1985 } 1986 1987 /** 1988 * Increment number of times Passpoint provider being uninstalled. 1989 */ incrementNumPasspointProviderUninstallation()1990 public void incrementNumPasspointProviderUninstallation() { 1991 synchronized (mLock) { 1992 mWifiLogProto.numPasspointProviderUninstallation++; 1993 } 1994 } 1995 1996 /** 1997 * Increment number of times Passpoint provider is uninstalled successfully. 1998 */ incrementNumPasspointProviderUninstallSuccess()1999 public void incrementNumPasspointProviderUninstallSuccess() { 2000 synchronized (mLock) { 2001 mWifiLogProto.numPasspointProviderUninstallSuccess++; 2002 } 2003 } 2004 2005 /** 2006 * Increment number of times we detected a radio mode change to MCC. 2007 */ incrementNumRadioModeChangeToMcc()2008 public void incrementNumRadioModeChangeToMcc() { 2009 synchronized (mLock) { 2010 mWifiLogProto.numRadioModeChangeToMcc++; 2011 } 2012 } 2013 2014 /** 2015 * Increment number of times we detected a radio mode change to SCC. 2016 */ incrementNumRadioModeChangeToScc()2017 public void incrementNumRadioModeChangeToScc() { 2018 synchronized (mLock) { 2019 mWifiLogProto.numRadioModeChangeToScc++; 2020 } 2021 } 2022 2023 /** 2024 * Increment number of times we detected a radio mode change to SBS. 2025 */ incrementNumRadioModeChangeToSbs()2026 public void incrementNumRadioModeChangeToSbs() { 2027 synchronized (mLock) { 2028 mWifiLogProto.numRadioModeChangeToSbs++; 2029 } 2030 } 2031 2032 /** 2033 * Increment number of times we detected a radio mode change to DBS. 2034 */ incrementNumRadioModeChangeToDbs()2035 public void incrementNumRadioModeChangeToDbs() { 2036 synchronized (mLock) { 2037 mWifiLogProto.numRadioModeChangeToDbs++; 2038 } 2039 } 2040 2041 /** 2042 * Increment number of times we detected a channel did not satisfy user band preference. 2043 */ incrementNumSoftApUserBandPreferenceUnsatisfied()2044 public void incrementNumSoftApUserBandPreferenceUnsatisfied() { 2045 synchronized (mLock) { 2046 mWifiLogProto.numSoftApUserBandPreferenceUnsatisfied++; 2047 } 2048 } 2049 2050 /** Increment the failure count of SAR sensor listener registration */ incrementNumSarSensorRegistrationFailures()2051 public void incrementNumSarSensorRegistrationFailures() { 2052 synchronized (mLock) { 2053 mWifiLogProto.numSarSensorRegistrationFailures++; 2054 } 2055 } 2056 2057 /** 2058 * Increment N-Way network selection decision histograms: 2059 * Counts the size of various sets of scanDetails within a scan, and increment the occurrence 2060 * of that size for the associated histogram. There are ten histograms generated for each 2061 * combination of: {SSID, BSSID} *{Total, Saved, Open, Saved_or_Open, Passpoint} 2062 * Only performs this count if isFullBand is true, otherwise, increments the partial scan count 2063 */ incrementAvailableNetworksHistograms(List<ScanDetail> scanDetails, boolean isFullBand)2064 public void incrementAvailableNetworksHistograms(List<ScanDetail> scanDetails, 2065 boolean isFullBand) { 2066 synchronized (mLock) { 2067 if (mWifiConfigManager == null || mWifiNetworkSelector == null 2068 || mPasspointManager == null) { 2069 return; 2070 } 2071 if (!isFullBand) { 2072 mWifiLogProto.partialAllSingleScanListenerResults++; 2073 return; 2074 } 2075 Set<ScanResultMatchInfo> ssids = new HashSet<ScanResultMatchInfo>(); 2076 int bssids = 0; 2077 Set<ScanResultMatchInfo> openSsids = new HashSet<ScanResultMatchInfo>(); 2078 int openBssids = 0; 2079 Set<ScanResultMatchInfo> savedSsids = new HashSet<ScanResultMatchInfo>(); 2080 int savedBssids = 0; 2081 // openOrSavedSsids calculated from union of savedSsids & openSsids 2082 int openOrSavedBssids = 0; 2083 Set<PasspointProvider> savedPasspointProviderProfiles = 2084 new HashSet<PasspointProvider>(); 2085 int savedPasspointProviderBssids = 0; 2086 int passpointR1Aps = 0; 2087 int passpointR2Aps = 0; 2088 Map<ANQPNetworkKey, Integer> passpointR1UniqueEss = new HashMap<>(); 2089 Map<ANQPNetworkKey, Integer> passpointR2UniqueEss = new HashMap<>(); 2090 int supporting80211mcAps = 0; 2091 for (ScanDetail scanDetail : scanDetails) { 2092 NetworkDetail networkDetail = scanDetail.getNetworkDetail(); 2093 ScanResult scanResult = scanDetail.getScanResult(); 2094 2095 // statistics to be collected for ALL APs (irrespective of signal power) 2096 if (networkDetail.is80211McResponderSupport()) { 2097 supporting80211mcAps++; 2098 } 2099 2100 ScanResultMatchInfo matchInfo = ScanResultMatchInfo.fromScanResult(scanResult); 2101 Pair<PasspointProvider, PasspointMatch> providerMatch = null; 2102 PasspointProvider passpointProvider = null; 2103 if (networkDetail.isInterworking()) { 2104 providerMatch = 2105 mPasspointManager.matchProvider(scanResult); 2106 passpointProvider = providerMatch != null ? providerMatch.first : null; 2107 2108 if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R1) { 2109 passpointR1Aps++; 2110 } else if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R2) { 2111 passpointR2Aps++; 2112 } 2113 2114 long bssid = 0; 2115 boolean validBssid = false; 2116 try { 2117 bssid = Utils.parseMac(scanResult.BSSID); 2118 validBssid = true; 2119 } catch (IllegalArgumentException e) { 2120 Log.e(TAG, 2121 "Invalid BSSID provided in the scan result: " + scanResult.BSSID); 2122 } 2123 if (validBssid) { 2124 ANQPNetworkKey uniqueEss = ANQPNetworkKey.buildKey(scanResult.SSID, bssid, 2125 scanResult.hessid, networkDetail.getAnqpDomainID()); 2126 if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R1) { 2127 Integer countObj = passpointR1UniqueEss.get(uniqueEss); 2128 int count = countObj == null ? 0 : countObj; 2129 passpointR1UniqueEss.put(uniqueEss, count + 1); 2130 } else if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R2) { 2131 Integer countObj = passpointR2UniqueEss.get(uniqueEss); 2132 int count = countObj == null ? 0 : countObj; 2133 passpointR2UniqueEss.put(uniqueEss, count + 1); 2134 } 2135 } 2136 2137 } 2138 2139 if (mWifiNetworkSelector.isSignalTooWeak(scanResult)) { 2140 continue; 2141 } 2142 2143 // statistics to be collected ONLY for those APs with sufficient signal power 2144 2145 ssids.add(matchInfo); 2146 bssids++; 2147 boolean isOpen = matchInfo.networkType == WifiConfiguration.SECURITY_TYPE_OPEN; 2148 WifiConfiguration config = 2149 mWifiConfigManager.getConfiguredNetworkForScanDetail(scanDetail); 2150 boolean isSaved = (config != null) && !config.isEphemeral() 2151 && !config.isPasspoint(); 2152 boolean isSavedPasspoint = passpointProvider != null; 2153 if (isOpen) { 2154 openSsids.add(matchInfo); 2155 openBssids++; 2156 } 2157 if (isSaved) { 2158 savedSsids.add(matchInfo); 2159 savedBssids++; 2160 } 2161 if (isOpen || isSaved) { 2162 openOrSavedBssids++; 2163 // Calculate openOrSavedSsids union later 2164 } 2165 if (isSavedPasspoint) { 2166 savedPasspointProviderProfiles.add(passpointProvider); 2167 savedPasspointProviderBssids++; 2168 } 2169 } 2170 mWifiLogProto.fullBandAllSingleScanListenerResults++; 2171 incrementTotalScanSsids(mTotalSsidsInScanHistogram, ssids.size()); 2172 incrementTotalScanResults(mTotalBssidsInScanHistogram, bssids); 2173 incrementSsid(mAvailableOpenSsidsInScanHistogram, openSsids.size()); 2174 incrementBssid(mAvailableOpenBssidsInScanHistogram, openBssids); 2175 incrementSsid(mAvailableSavedSsidsInScanHistogram, savedSsids.size()); 2176 incrementBssid(mAvailableSavedBssidsInScanHistogram, savedBssids); 2177 openSsids.addAll(savedSsids); // openSsids = Union(openSsids, savedSsids) 2178 incrementSsid(mAvailableOpenOrSavedSsidsInScanHistogram, openSsids.size()); 2179 incrementBssid(mAvailableOpenOrSavedBssidsInScanHistogram, openOrSavedBssids); 2180 incrementSsid(mAvailableSavedPasspointProviderProfilesInScanHistogram, 2181 savedPasspointProviderProfiles.size()); 2182 incrementBssid(mAvailableSavedPasspointProviderBssidsInScanHistogram, 2183 savedPasspointProviderBssids); 2184 incrementTotalPasspointAps(mObservedHotspotR1ApInScanHistogram, passpointR1Aps); 2185 incrementTotalPasspointAps(mObservedHotspotR2ApInScanHistogram, passpointR2Aps); 2186 incrementTotalUniquePasspointEss(mObservedHotspotR1EssInScanHistogram, 2187 passpointR1UniqueEss.size()); 2188 incrementTotalUniquePasspointEss(mObservedHotspotR2EssInScanHistogram, 2189 passpointR2UniqueEss.size()); 2190 for (Integer count : passpointR1UniqueEss.values()) { 2191 incrementPasspointPerUniqueEss(mObservedHotspotR1ApsPerEssInScanHistogram, count); 2192 } 2193 for (Integer count : passpointR2UniqueEss.values()) { 2194 incrementPasspointPerUniqueEss(mObservedHotspotR2ApsPerEssInScanHistogram, count); 2195 } 2196 increment80211mcAps(mObserved80211mcApInScanHistogram, supporting80211mcAps); 2197 } 2198 } 2199 2200 /** 2201 * TODO: (b/72443859) Use notifierTag param to separate metrics for OpenNetworkNotifier and 2202 * CarrierNetworkNotifier, for this method and all other related metrics. 2203 */ 2204 /** Increments the occurence of a "Connect to Network" notification. */ incrementConnectToNetworkNotification(String notifierTag, int notificationType)2205 public void incrementConnectToNetworkNotification(String notifierTag, int notificationType) { 2206 synchronized (mLock) { 2207 int count = mConnectToNetworkNotificationCount.get(notificationType); 2208 mConnectToNetworkNotificationCount.put(notificationType, count + 1); 2209 } 2210 } 2211 2212 /** Increments the occurence of an "Connect to Network" notification user action. */ incrementConnectToNetworkNotificationAction(String notifierTag, int notificationType, int actionType)2213 public void incrementConnectToNetworkNotificationAction(String notifierTag, 2214 int notificationType, int actionType) { 2215 synchronized (mLock) { 2216 int key = notificationType * CONNECT_TO_NETWORK_NOTIFICATION_ACTION_KEY_MULTIPLIER 2217 + actionType; 2218 int count = mConnectToNetworkNotificationActionCount.get(key); 2219 mConnectToNetworkNotificationActionCount.put(key, count + 1); 2220 } 2221 } 2222 2223 /** 2224 * Sets the number of SSIDs blacklisted from recommendation by the open network notification 2225 * recommender. 2226 */ setNetworkRecommenderBlacklistSize(String notifierTag, int size)2227 public void setNetworkRecommenderBlacklistSize(String notifierTag, int size) { 2228 synchronized (mLock) { 2229 mOpenNetworkRecommenderBlacklistSize = size; 2230 } 2231 } 2232 2233 /** Sets if the available network notification feature is enabled. */ setIsWifiNetworksAvailableNotificationEnabled(String notifierTag, boolean enabled)2234 public void setIsWifiNetworksAvailableNotificationEnabled(String notifierTag, boolean enabled) { 2235 synchronized (mLock) { 2236 mIsWifiNetworksAvailableNotificationOn = enabled; 2237 } 2238 } 2239 2240 /** Increments the occurence of connection attempts that were initiated unsuccessfully */ incrementNumNetworkRecommendationUpdates(String notifierTag)2241 public void incrementNumNetworkRecommendationUpdates(String notifierTag) { 2242 synchronized (mLock) { 2243 mNumOpenNetworkRecommendationUpdates++; 2244 } 2245 } 2246 2247 /** Increments the occurence of connection attempts that were initiated unsuccessfully */ incrementNumNetworkConnectMessageFailedToSend(String notifierTag)2248 public void incrementNumNetworkConnectMessageFailedToSend(String notifierTag) { 2249 synchronized (mLock) { 2250 mNumOpenNetworkConnectMessageFailedToSend++; 2251 } 2252 } 2253 2254 /** Sets if Connected MAC Randomization feature is enabled */ setIsMacRandomizationOn(boolean enabled)2255 public void setIsMacRandomizationOn(boolean enabled) { 2256 synchronized (mLock) { 2257 mIsMacRandomizationOn = enabled; 2258 } 2259 } 2260 2261 /** Log firmware alert related metrics */ logFirmwareAlert(int errorCode)2262 public void logFirmwareAlert(int errorCode) { 2263 incrementAlertReasonCount(errorCode); 2264 logWifiIsUnusableEvent(WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT, errorCode); 2265 addToWifiUsabilityStatsList(WifiUsabilityStats.LABEL_BAD, 2266 WifiUsabilityStats.TYPE_FIRMWARE_ALERT, errorCode); 2267 } 2268 2269 public static final String PROTO_DUMP_ARG = "wifiMetricsProto"; 2270 public static final String CLEAN_DUMP_ARG = "clean"; 2271 2272 /** 2273 * Dump all WifiMetrics. Collects some metrics from ConfigStore, Settings and WifiManager 2274 * at this time. 2275 * 2276 * @param fd unused 2277 * @param pw PrintWriter for writing dump to 2278 * @param args [wifiMetricsProto [clean]] 2279 */ dump(FileDescriptor fd, PrintWriter pw, String[] args)2280 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2281 synchronized (mLock) { 2282 consolidateScoringParams(); 2283 if (args != null && args.length > 0 && PROTO_DUMP_ARG.equals(args[0])) { 2284 // Dump serialized WifiLog proto 2285 consolidateProto(); 2286 2287 byte[] wifiMetricsProto = WifiMetricsProto.WifiLog.toByteArray(mWifiLogProto); 2288 String metricsProtoDump = Base64.encodeToString(wifiMetricsProto, Base64.DEFAULT); 2289 if (args.length > 1 && CLEAN_DUMP_ARG.equals(args[1])) { 2290 // Output metrics proto bytes (base64) and nothing else 2291 pw.print(metricsProtoDump); 2292 } else { 2293 // Tag the start and end of the metrics proto bytes 2294 pw.println("WifiMetrics:"); 2295 pw.println(metricsProtoDump); 2296 pw.println("EndWifiMetrics"); 2297 } 2298 clear(); 2299 } else { 2300 pw.println("WifiMetrics:"); 2301 pw.println("mConnectionEvents:"); 2302 for (ConnectionEvent event : mConnectionEventList) { 2303 String eventLine = event.toString(); 2304 if (event == mCurrentConnectionEvent) { 2305 eventLine += "CURRENTLY OPEN EVENT"; 2306 } 2307 pw.println(eventLine); 2308 } 2309 pw.println("mWifiLogProto.numSavedNetworks=" + mWifiLogProto.numSavedNetworks); 2310 pw.println("mWifiLogProto.numSavedNetworksWithMacRandomization=" 2311 + mWifiLogProto.numSavedNetworksWithMacRandomization); 2312 pw.println("mWifiLogProto.numOpenNetworks=" + mWifiLogProto.numOpenNetworks); 2313 pw.println("mWifiLogProto.numLegacyPersonalNetworks=" 2314 + mWifiLogProto.numLegacyPersonalNetworks); 2315 pw.println("mWifiLogProto.numLegacyEnterpriseNetworks=" 2316 + mWifiLogProto.numLegacyEnterpriseNetworks); 2317 pw.println("mWifiLogProto.numEnhancedOpenNetworks=" 2318 + mWifiLogProto.numEnhancedOpenNetworks); 2319 pw.println("mWifiLogProto.numWpa3PersonalNetworks=" 2320 + mWifiLogProto.numWpa3PersonalNetworks); 2321 pw.println("mWifiLogProto.numWpa3EnterpriseNetworks=" 2322 + mWifiLogProto.numWpa3EnterpriseNetworks); 2323 pw.println("mWifiLogProto.numHiddenNetworks=" + mWifiLogProto.numHiddenNetworks); 2324 pw.println("mWifiLogProto.numPasspointNetworks=" 2325 + mWifiLogProto.numPasspointNetworks); 2326 pw.println("mWifiLogProto.isLocationEnabled=" + mWifiLogProto.isLocationEnabled); 2327 pw.println("mWifiLogProto.isScanningAlwaysEnabled=" 2328 + mWifiLogProto.isScanningAlwaysEnabled); 2329 pw.println("mWifiLogProto.numNetworksAddedByUser=" 2330 + mWifiLogProto.numNetworksAddedByUser); 2331 pw.println("mWifiLogProto.numNetworksAddedByApps=" 2332 + mWifiLogProto.numNetworksAddedByApps); 2333 pw.println("mWifiLogProto.numNonEmptyScanResults=" 2334 + mWifiLogProto.numNonEmptyScanResults); 2335 pw.println("mWifiLogProto.numEmptyScanResults=" 2336 + mWifiLogProto.numEmptyScanResults); 2337 pw.println("mWifiLogProto.numConnecitvityOneshotScans=" 2338 + mWifiLogProto.numConnectivityOneshotScans); 2339 pw.println("mWifiLogProto.numOneshotScans=" 2340 + mWifiLogProto.numOneshotScans); 2341 pw.println("mWifiLogProto.numOneshotHasDfsChannelScans=" 2342 + mWifiLogProto.numOneshotHasDfsChannelScans); 2343 pw.println("mWifiLogProto.numBackgroundScans=" 2344 + mWifiLogProto.numBackgroundScans); 2345 pw.println("mWifiLogProto.numExternalAppOneshotScanRequests=" 2346 + mWifiLogProto.numExternalAppOneshotScanRequests); 2347 pw.println("mWifiLogProto.numExternalForegroundAppOneshotScanRequestsThrottled=" 2348 + mWifiLogProto.numExternalForegroundAppOneshotScanRequestsThrottled); 2349 pw.println("mWifiLogProto.numExternalBackgroundAppOneshotScanRequestsThrottled=" 2350 + mWifiLogProto.numExternalBackgroundAppOneshotScanRequestsThrottled); 2351 2352 pw.println("mScanReturnEntries:"); 2353 pw.println(" SCAN_UNKNOWN: " + getScanReturnEntry( 2354 WifiMetricsProto.WifiLog.SCAN_UNKNOWN)); 2355 pw.println(" SCAN_SUCCESS: " + getScanReturnEntry( 2356 WifiMetricsProto.WifiLog.SCAN_SUCCESS)); 2357 pw.println(" SCAN_FAILURE_INTERRUPTED: " + getScanReturnEntry( 2358 WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED)); 2359 pw.println(" SCAN_FAILURE_INVALID_CONFIGURATION: " + getScanReturnEntry( 2360 WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION)); 2361 pw.println(" FAILURE_WIFI_DISABLED: " + getScanReturnEntry( 2362 WifiMetricsProto.WifiLog.FAILURE_WIFI_DISABLED)); 2363 2364 pw.println("mSystemStateEntries: <state><screenOn> : <scansInitiated>"); 2365 pw.println(" WIFI_UNKNOWN ON: " 2366 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, true)); 2367 pw.println(" WIFI_DISABLED ON: " 2368 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISABLED, true)); 2369 pw.println(" WIFI_DISCONNECTED ON: " 2370 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED, true)); 2371 pw.println(" WIFI_ASSOCIATED ON: " 2372 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, true)); 2373 pw.println(" WIFI_UNKNOWN OFF: " 2374 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, false)); 2375 pw.println(" WIFI_DISABLED OFF: " 2376 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISABLED, false)); 2377 pw.println(" WIFI_DISCONNECTED OFF: " 2378 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED, false)); 2379 pw.println(" WIFI_ASSOCIATED OFF: " 2380 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, false)); 2381 pw.println("mWifiLogProto.numConnectivityWatchdogPnoGood=" 2382 + mWifiLogProto.numConnectivityWatchdogPnoGood); 2383 pw.println("mWifiLogProto.numConnectivityWatchdogPnoBad=" 2384 + mWifiLogProto.numConnectivityWatchdogPnoBad); 2385 pw.println("mWifiLogProto.numConnectivityWatchdogBackgroundGood=" 2386 + mWifiLogProto.numConnectivityWatchdogBackgroundGood); 2387 pw.println("mWifiLogProto.numConnectivityWatchdogBackgroundBad=" 2388 + mWifiLogProto.numConnectivityWatchdogBackgroundBad); 2389 pw.println("mWifiLogProto.numLastResortWatchdogTriggers=" 2390 + mWifiLogProto.numLastResortWatchdogTriggers); 2391 pw.println("mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal=" 2392 + mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal); 2393 pw.println("mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal=" 2394 + mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal); 2395 pw.println("mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal=" 2396 + mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal); 2397 pw.println("mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal=" 2398 + mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal); 2399 pw.println("mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal=" 2400 + mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal); 2401 pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation=" 2402 + mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation); 2403 pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication=" 2404 + mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication); 2405 pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp=" 2406 + mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp); 2407 pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadOther=" 2408 + mWifiLogProto.numLastResortWatchdogTriggersWithBadOther); 2409 pw.println("mWifiLogProto.numLastResortWatchdogSuccesses=" 2410 + mWifiLogProto.numLastResortWatchdogSuccesses); 2411 pw.println("mWifiLogProto.watchdogTotalConnectionFailureCountAfterTrigger=" 2412 + mWifiLogProto.watchdogTotalConnectionFailureCountAfterTrigger); 2413 pw.println("mWifiLogProto.watchdogTriggerToConnectionSuccessDurationMs=" 2414 + mWifiLogProto.watchdogTriggerToConnectionSuccessDurationMs); 2415 pw.println("mWifiLogProto.recordDurationSec=" 2416 + ((mClock.getElapsedSinceBootMillis() / 1000) - mRecordStartTimeSec)); 2417 2418 try { 2419 JSONObject rssiMap = new JSONObject(); 2420 for (Map.Entry<Integer, SparseIntArray> entry : mRssiPollCountsMap.entrySet()) { 2421 int frequency = entry.getKey(); 2422 final SparseIntArray histogram = entry.getValue(); 2423 JSONArray histogramElements = new JSONArray(); 2424 for (int i = MIN_RSSI_POLL; i <= MAX_RSSI_POLL; i++) { 2425 int count = histogram.get(i); 2426 if (count == 0) { 2427 continue; 2428 } 2429 JSONObject histogramElement = new JSONObject(); 2430 histogramElement.put(Integer.toString(i), count); 2431 histogramElements.put(histogramElement); 2432 } 2433 rssiMap.put(Integer.toString(frequency), histogramElements); 2434 } 2435 pw.println("mWifiLogProto.rssiPollCount: " + rssiMap.toString()); 2436 } catch (JSONException e) { 2437 pw.println("JSONException occurred: " + e.getMessage()); 2438 } 2439 2440 pw.println("mWifiLogProto.rssiPollDeltaCount: Printing counts for [" 2441 + MIN_RSSI_DELTA + ", " + MAX_RSSI_DELTA + "]"); 2442 StringBuilder sb = new StringBuilder(); 2443 for (int i = MIN_RSSI_DELTA; i <= MAX_RSSI_DELTA; i++) { 2444 sb.append(mRssiDeltaCounts.get(i) + " "); 2445 } 2446 pw.println(" " + sb.toString()); 2447 pw.println("mWifiLogProto.linkSpeedCounts: "); 2448 sb.setLength(0); 2449 for (int i = 0; i < mLinkSpeedCounts.size(); i++) { 2450 LinkSpeedCount linkSpeedCount = mLinkSpeedCounts.valueAt(i); 2451 sb.append(linkSpeedCount.linkSpeedMbps).append(":{") 2452 .append(linkSpeedCount.count).append(", ") 2453 .append(linkSpeedCount.rssiSumDbm).append(", ") 2454 .append(linkSpeedCount.rssiSumOfSquaresDbmSq).append("} "); 2455 } 2456 if (sb.length() > 0) { 2457 pw.println(sb.toString()); 2458 } 2459 pw.print("mWifiLogProto.alertReasonCounts="); 2460 sb.setLength(0); 2461 for (int i = WifiLoggerHal.WIFI_ALERT_REASON_MIN; 2462 i <= WifiLoggerHal.WIFI_ALERT_REASON_MAX; i++) { 2463 int count = mWifiAlertReasonCounts.get(i); 2464 if (count > 0) { 2465 sb.append("(" + i + "," + count + "),"); 2466 } 2467 } 2468 if (sb.length() > 1) { 2469 sb.setLength(sb.length() - 1); // strip trailing comma 2470 pw.println(sb.toString()); 2471 } else { 2472 pw.println("()"); 2473 } 2474 pw.println("mWifiLogProto.numTotalScanResults=" 2475 + mWifiLogProto.numTotalScanResults); 2476 pw.println("mWifiLogProto.numOpenNetworkScanResults=" 2477 + mWifiLogProto.numOpenNetworkScanResults); 2478 pw.println("mWifiLogProto.numLegacyPersonalNetworkScanResults=" 2479 + mWifiLogProto.numLegacyPersonalNetworkScanResults); 2480 pw.println("mWifiLogProto.numLegacyEnterpriseNetworkScanResults=" 2481 + mWifiLogProto.numLegacyEnterpriseNetworkScanResults); 2482 pw.println("mWifiLogProto.numEnhancedOpenNetworkScanResults=" 2483 + mWifiLogProto.numEnhancedOpenNetworkScanResults); 2484 pw.println("mWifiLogProto.numWpa3PersonalNetworkScanResults=" 2485 + mWifiLogProto.numWpa3PersonalNetworkScanResults); 2486 pw.println("mWifiLogProto.numWpa3EnterpriseNetworkScanResults=" 2487 + mWifiLogProto.numWpa3EnterpriseNetworkScanResults); 2488 pw.println("mWifiLogProto.numHiddenNetworkScanResults=" 2489 + mWifiLogProto.numHiddenNetworkScanResults); 2490 pw.println("mWifiLogProto.numHotspot2R1NetworkScanResults=" 2491 + mWifiLogProto.numHotspot2R1NetworkScanResults); 2492 pw.println("mWifiLogProto.numHotspot2R2NetworkScanResults=" 2493 + mWifiLogProto.numHotspot2R2NetworkScanResults); 2494 pw.println("mWifiLogProto.numScans=" + mWifiLogProto.numScans); 2495 pw.println("mWifiLogProto.WifiScoreCount: [" + MIN_WIFI_SCORE + ", " 2496 + MAX_WIFI_SCORE + "]"); 2497 for (int i = 0; i <= MAX_WIFI_SCORE; i++) { 2498 pw.print(mWifiScoreCounts.get(i) + " "); 2499 } 2500 pw.println(); // add a line after wifi scores 2501 pw.println("mWifiLogProto.WifiUsabilityScoreCount: [" + MIN_WIFI_USABILITY_SCORE 2502 + ", " + MAX_WIFI_USABILITY_SCORE + "]"); 2503 for (int i = MIN_WIFI_USABILITY_SCORE; i <= MAX_WIFI_USABILITY_SCORE; i++) { 2504 pw.print(mWifiUsabilityScoreCounts.get(i) + " "); 2505 } 2506 pw.println(); // add a line after wifi usability scores 2507 pw.println("mWifiLogProto.SoftApManagerReturnCodeCounts:"); 2508 pw.println(" SUCCESS: " + mSoftApManagerReturnCodeCounts.get( 2509 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_STARTED_SUCCESSFULLY)); 2510 pw.println(" FAILED_GENERAL_ERROR: " + mSoftApManagerReturnCodeCounts.get( 2511 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_GENERAL_ERROR)); 2512 pw.println(" FAILED_NO_CHANNEL: " + mSoftApManagerReturnCodeCounts.get( 2513 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_NO_CHANNEL)); 2514 pw.print("\n"); 2515 pw.println("mWifiLogProto.numHalCrashes=" 2516 + mWifiLogProto.numHalCrashes); 2517 pw.println("mWifiLogProto.numWificondCrashes=" 2518 + mWifiLogProto.numWificondCrashes); 2519 pw.println("mWifiLogProto.numSupplicantCrashes=" 2520 + mWifiLogProto.numSupplicantCrashes); 2521 pw.println("mWifiLogProto.numHostapdCrashes=" 2522 + mWifiLogProto.numHostapdCrashes); 2523 pw.println("mWifiLogProto.numSetupClientInterfaceFailureDueToHal=" 2524 + mWifiLogProto.numSetupClientInterfaceFailureDueToHal); 2525 pw.println("mWifiLogProto.numSetupClientInterfaceFailureDueToWificond=" 2526 + mWifiLogProto.numSetupClientInterfaceFailureDueToWificond); 2527 pw.println("mWifiLogProto.numSetupClientInterfaceFailureDueToSupplicant=" 2528 + mWifiLogProto.numSetupClientInterfaceFailureDueToSupplicant); 2529 pw.println("mWifiLogProto.numSetupSoftApInterfaceFailureDueToHal=" 2530 + mWifiLogProto.numSetupSoftApInterfaceFailureDueToHal); 2531 pw.println("mWifiLogProto.numSetupSoftApInterfaceFailureDueToWificond=" 2532 + mWifiLogProto.numSetupSoftApInterfaceFailureDueToWificond); 2533 pw.println("mWifiLogProto.numSetupSoftApInterfaceFailureDueToHostapd=" 2534 + mWifiLogProto.numSetupSoftApInterfaceFailureDueToHostapd); 2535 pw.println("mWifiLogProto.numSarSensorRegistrationFailures=" 2536 + mWifiLogProto.numSarSensorRegistrationFailures); 2537 pw.println("StaEventList:"); 2538 for (StaEventWithTime event : mStaEventList) { 2539 pw.println(event); 2540 } 2541 2542 pw.println("mWifiLogProto.numPasspointProviders=" 2543 + mWifiLogProto.numPasspointProviders); 2544 pw.println("mWifiLogProto.numPasspointProviderInstallation=" 2545 + mWifiLogProto.numPasspointProviderInstallation); 2546 pw.println("mWifiLogProto.numPasspointProviderInstallSuccess=" 2547 + mWifiLogProto.numPasspointProviderInstallSuccess); 2548 pw.println("mWifiLogProto.numPasspointProviderUninstallation=" 2549 + mWifiLogProto.numPasspointProviderUninstallation); 2550 pw.println("mWifiLogProto.numPasspointProviderUninstallSuccess=" 2551 + mWifiLogProto.numPasspointProviderUninstallSuccess); 2552 pw.println("mWifiLogProto.numPasspointProvidersSuccessfullyConnected=" 2553 + mWifiLogProto.numPasspointProvidersSuccessfullyConnected); 2554 2555 pw.println("mWifiLogProto.installedPasspointProfileTypeForR1:" 2556 + mInstalledPasspointProfileTypeForR1); 2557 pw.println("mWifiLogProto.installedPasspointProfileTypeForR2:" 2558 + mInstalledPasspointProfileTypeForR2); 2559 2560 pw.println("mWifiLogProto.passpointProvisionStats.numProvisionSuccess=" 2561 + mNumProvisionSuccess); 2562 pw.println("mWifiLogProto.passpointProvisionStats.provisionFailureCount:" 2563 + mPasspointProvisionFailureCounts); 2564 2565 pw.println("mWifiLogProto.numRadioModeChangeToMcc=" 2566 + mWifiLogProto.numRadioModeChangeToMcc); 2567 pw.println("mWifiLogProto.numRadioModeChangeToScc=" 2568 + mWifiLogProto.numRadioModeChangeToScc); 2569 pw.println("mWifiLogProto.numRadioModeChangeToSbs=" 2570 + mWifiLogProto.numRadioModeChangeToSbs); 2571 pw.println("mWifiLogProto.numRadioModeChangeToDbs=" 2572 + mWifiLogProto.numRadioModeChangeToDbs); 2573 pw.println("mWifiLogProto.numSoftApUserBandPreferenceUnsatisfied=" 2574 + mWifiLogProto.numSoftApUserBandPreferenceUnsatisfied); 2575 pw.println("mTotalSsidsInScanHistogram:" 2576 + mTotalSsidsInScanHistogram.toString()); 2577 pw.println("mTotalBssidsInScanHistogram:" 2578 + mTotalBssidsInScanHistogram.toString()); 2579 pw.println("mAvailableOpenSsidsInScanHistogram:" 2580 + mAvailableOpenSsidsInScanHistogram.toString()); 2581 pw.println("mAvailableOpenBssidsInScanHistogram:" 2582 + mAvailableOpenBssidsInScanHistogram.toString()); 2583 pw.println("mAvailableSavedSsidsInScanHistogram:" 2584 + mAvailableSavedSsidsInScanHistogram.toString()); 2585 pw.println("mAvailableSavedBssidsInScanHistogram:" 2586 + mAvailableSavedBssidsInScanHistogram.toString()); 2587 pw.println("mAvailableOpenOrSavedSsidsInScanHistogram:" 2588 + mAvailableOpenOrSavedSsidsInScanHistogram.toString()); 2589 pw.println("mAvailableOpenOrSavedBssidsInScanHistogram:" 2590 + mAvailableOpenOrSavedBssidsInScanHistogram.toString()); 2591 pw.println("mAvailableSavedPasspointProviderProfilesInScanHistogram:" 2592 + mAvailableSavedPasspointProviderProfilesInScanHistogram.toString()); 2593 pw.println("mAvailableSavedPasspointProviderBssidsInScanHistogram:" 2594 + mAvailableSavedPasspointProviderBssidsInScanHistogram.toString()); 2595 pw.println("mWifiLogProto.partialAllSingleScanListenerResults=" 2596 + mWifiLogProto.partialAllSingleScanListenerResults); 2597 pw.println("mWifiLogProto.fullBandAllSingleScanListenerResults=" 2598 + mWifiLogProto.fullBandAllSingleScanListenerResults); 2599 pw.println("mWifiAwareMetrics:"); 2600 mWifiAwareMetrics.dump(fd, pw, args); 2601 pw.println("mRttMetrics:"); 2602 mRttMetrics.dump(fd, pw, args); 2603 2604 pw.println("mPnoScanMetrics.numPnoScanAttempts=" 2605 + mPnoScanMetrics.numPnoScanAttempts); 2606 pw.println("mPnoScanMetrics.numPnoScanFailed=" 2607 + mPnoScanMetrics.numPnoScanFailed); 2608 pw.println("mPnoScanMetrics.numPnoScanStartedOverOffload=" 2609 + mPnoScanMetrics.numPnoScanStartedOverOffload); 2610 pw.println("mPnoScanMetrics.numPnoScanFailedOverOffload=" 2611 + mPnoScanMetrics.numPnoScanFailedOverOffload); 2612 pw.println("mPnoScanMetrics.numPnoFoundNetworkEvents=" 2613 + mPnoScanMetrics.numPnoFoundNetworkEvents); 2614 2615 pw.println("mWifiLinkLayerUsageStats.loggingDurationMs=" 2616 + mWifiLinkLayerUsageStats.loggingDurationMs); 2617 pw.println("mWifiLinkLayerUsageStats.radioOnTimeMs=" 2618 + mWifiLinkLayerUsageStats.radioOnTimeMs); 2619 pw.println("mWifiLinkLayerUsageStats.radioTxTimeMs=" 2620 + mWifiLinkLayerUsageStats.radioTxTimeMs); 2621 pw.println("mWifiLinkLayerUsageStats.radioRxTimeMs=" 2622 + mWifiLinkLayerUsageStats.radioRxTimeMs); 2623 pw.println("mWifiLinkLayerUsageStats.radioScanTimeMs=" 2624 + mWifiLinkLayerUsageStats.radioScanTimeMs); 2625 pw.println("mWifiLinkLayerUsageStats.radioNanScanTimeMs=" 2626 + mWifiLinkLayerUsageStats.radioNanScanTimeMs); 2627 pw.println("mWifiLinkLayerUsageStats.radioBackgroundScanTimeMs=" 2628 + mWifiLinkLayerUsageStats.radioBackgroundScanTimeMs); 2629 pw.println("mWifiLinkLayerUsageStats.radioRoamScanTimeMs=" 2630 + mWifiLinkLayerUsageStats.radioRoamScanTimeMs); 2631 pw.println("mWifiLinkLayerUsageStats.radioPnoScanTimeMs=" 2632 + mWifiLinkLayerUsageStats.radioPnoScanTimeMs); 2633 pw.println("mWifiLinkLayerUsageStats.radioHs20ScanTimeMs=" 2634 + mWifiLinkLayerUsageStats.radioHs20ScanTimeMs); 2635 2636 pw.println("mWifiLogProto.connectToNetworkNotificationCount=" 2637 + mConnectToNetworkNotificationCount.toString()); 2638 pw.println("mWifiLogProto.connectToNetworkNotificationActionCount=" 2639 + mConnectToNetworkNotificationActionCount.toString()); 2640 pw.println("mWifiLogProto.openNetworkRecommenderBlacklistSize=" 2641 + mOpenNetworkRecommenderBlacklistSize); 2642 pw.println("mWifiLogProto.isWifiNetworksAvailableNotificationOn=" 2643 + mIsWifiNetworksAvailableNotificationOn); 2644 pw.println("mWifiLogProto.numOpenNetworkRecommendationUpdates=" 2645 + mNumOpenNetworkRecommendationUpdates); 2646 pw.println("mWifiLogProto.numOpenNetworkConnectMessageFailedToSend=" 2647 + mNumOpenNetworkConnectMessageFailedToSend); 2648 2649 pw.println("mWifiLogProto.observedHotspotR1ApInScanHistogram=" 2650 + mObservedHotspotR1ApInScanHistogram); 2651 pw.println("mWifiLogProto.observedHotspotR2ApInScanHistogram=" 2652 + mObservedHotspotR2ApInScanHistogram); 2653 pw.println("mWifiLogProto.observedHotspotR1EssInScanHistogram=" 2654 + mObservedHotspotR1EssInScanHistogram); 2655 pw.println("mWifiLogProto.observedHotspotR2EssInScanHistogram=" 2656 + mObservedHotspotR2EssInScanHistogram); 2657 pw.println("mWifiLogProto.observedHotspotR1ApsPerEssInScanHistogram=" 2658 + mObservedHotspotR1ApsPerEssInScanHistogram); 2659 pw.println("mWifiLogProto.observedHotspotR2ApsPerEssInScanHistogram=" 2660 + mObservedHotspotR2ApsPerEssInScanHistogram); 2661 2662 pw.println("mWifiLogProto.observed80211mcSupportingApsInScanHistogram" 2663 + mObserved80211mcApInScanHistogram); 2664 2665 pw.println("mSoftApTetheredEvents:"); 2666 for (SoftApConnectedClientsEvent event : mSoftApEventListTethered) { 2667 StringBuilder eventLine = new StringBuilder(); 2668 eventLine.append("event_type=" + event.eventType); 2669 eventLine.append(",time_stamp_millis=" + event.timeStampMillis); 2670 eventLine.append(",num_connected_clients=" + event.numConnectedClients); 2671 eventLine.append(",channel_frequency=" + event.channelFrequency); 2672 eventLine.append(",channel_bandwidth=" + event.channelBandwidth); 2673 pw.println(eventLine.toString()); 2674 } 2675 pw.println("mSoftApLocalOnlyEvents:"); 2676 for (SoftApConnectedClientsEvent event : mSoftApEventListLocalOnly) { 2677 StringBuilder eventLine = new StringBuilder(); 2678 eventLine.append("event_type=" + event.eventType); 2679 eventLine.append(",time_stamp_millis=" + event.timeStampMillis); 2680 eventLine.append(",num_connected_clients=" + event.numConnectedClients); 2681 eventLine.append(",channel_frequency=" + event.channelFrequency); 2682 eventLine.append(",channel_bandwidth=" + event.channelBandwidth); 2683 pw.println(eventLine.toString()); 2684 } 2685 2686 pw.println("mWpsMetrics.numWpsAttempts=" 2687 + mWpsMetrics.numWpsAttempts); 2688 pw.println("mWpsMetrics.numWpsSuccess=" 2689 + mWpsMetrics.numWpsSuccess); 2690 pw.println("mWpsMetrics.numWpsStartFailure=" 2691 + mWpsMetrics.numWpsStartFailure); 2692 pw.println("mWpsMetrics.numWpsOverlapFailure=" 2693 + mWpsMetrics.numWpsOverlapFailure); 2694 pw.println("mWpsMetrics.numWpsTimeoutFailure=" 2695 + mWpsMetrics.numWpsTimeoutFailure); 2696 pw.println("mWpsMetrics.numWpsOtherConnectionFailure=" 2697 + mWpsMetrics.numWpsOtherConnectionFailure); 2698 pw.println("mWpsMetrics.numWpsSupplicantFailure=" 2699 + mWpsMetrics.numWpsSupplicantFailure); 2700 pw.println("mWpsMetrics.numWpsCancellation=" 2701 + mWpsMetrics.numWpsCancellation); 2702 2703 mWifiPowerMetrics.dump(pw); 2704 mWifiWakeMetrics.dump(pw); 2705 2706 pw.println("mWifiLogProto.isMacRandomizationOn=" + mIsMacRandomizationOn); 2707 pw.println("mWifiLogProto.scoreExperimentId=" + mWifiLogProto.scoreExperimentId); 2708 pw.println("mExperimentValues.wifiIsUnusableLoggingEnabled=" 2709 + mExperimentValues.wifiIsUnusableLoggingEnabled); 2710 pw.println("mExperimentValues.wifiDataStallMinTxBad=" 2711 + mExperimentValues.wifiDataStallMinTxBad); 2712 pw.println("mExperimentValues.wifiDataStallMinTxSuccessWithoutRx=" 2713 + mExperimentValues.wifiDataStallMinTxSuccessWithoutRx); 2714 pw.println("mExperimentValues.linkSpeedCountsLoggingEnabled=" 2715 + mExperimentValues.linkSpeedCountsLoggingEnabled); 2716 pw.println("WifiIsUnusableEventList: "); 2717 for (WifiIsUnusableWithTime event : mWifiIsUnusableList) { 2718 pw.println(event); 2719 } 2720 pw.println("Hardware Version: " + SystemProperties.get("ro.boot.revision", "")); 2721 2722 pw.println("mWifiUsabilityStatsEntriesList:"); 2723 for (WifiUsabilityStatsEntry stats : mWifiUsabilityStatsEntriesList) { 2724 printWifiUsabilityStatsEntry(pw, stats); 2725 } 2726 pw.println("mWifiUsabilityStatsList:"); 2727 for (WifiUsabilityStats stats : mWifiUsabilityStatsListGood) { 2728 pw.println("\nlabel=" + stats.label); 2729 pw.println("\ntrigger_type=" + stats.triggerType); 2730 pw.println("\ntime_stamp_ms=" + stats.timeStampMs); 2731 for (WifiUsabilityStatsEntry entry : stats.stats) { 2732 printWifiUsabilityStatsEntry(pw, entry); 2733 } 2734 } 2735 for (WifiUsabilityStats stats : mWifiUsabilityStatsListBad) { 2736 pw.println("\nlabel=" + stats.label); 2737 pw.println("\ntrigger_type=" + stats.triggerType); 2738 pw.println("\ntime_stamp_ms=" + stats.timeStampMs); 2739 for (WifiUsabilityStatsEntry entry : stats.stats) { 2740 printWifiUsabilityStatsEntry(pw, entry); 2741 } 2742 } 2743 2744 pw.println("mMobilityStatePnoStatsMap:"); 2745 for (int i = 0; i < mMobilityStatePnoStatsMap.size(); i++) { 2746 printDeviceMobilityStatePnoScanStats(pw, mMobilityStatePnoStatsMap.valueAt(i)); 2747 } 2748 2749 mWifiP2pMetrics.dump(pw); 2750 pw.println("mDppMetrics:"); 2751 mDppMetrics.dump(pw); 2752 2753 pw.println("mWifiConfigStoreReadDurationHistogram:" 2754 + mWifiConfigStoreReadDurationHistogram.toString()); 2755 pw.println("mWifiConfigStoreWriteDurationHistogram:" 2756 + mWifiConfigStoreWriteDurationHistogram.toString()); 2757 2758 pw.println("mLinkProbeSuccessRssiCounts:" + mLinkProbeSuccessRssiCounts); 2759 pw.println("mLinkProbeFailureRssiCounts:" + mLinkProbeFailureRssiCounts); 2760 pw.println("mLinkProbeSuccessLinkSpeedCounts:" + mLinkProbeSuccessLinkSpeedCounts); 2761 pw.println("mLinkProbeFailureLinkSpeedCounts:" + mLinkProbeFailureLinkSpeedCounts); 2762 pw.println("mLinkProbeSuccessSecondsSinceLastTxSuccessHistogram:" 2763 + mLinkProbeSuccessSecondsSinceLastTxSuccessHistogram); 2764 pw.println("mLinkProbeFailureSecondsSinceLastTxSuccessHistogram:" 2765 + mLinkProbeFailureSecondsSinceLastTxSuccessHistogram); 2766 pw.println("mLinkProbeSuccessElapsedTimeMsHistogram:" 2767 + mLinkProbeSuccessElapsedTimeMsHistogram); 2768 pw.println("mLinkProbeFailureReasonCounts:" + mLinkProbeFailureReasonCounts); 2769 pw.println("mLinkProbeExperimentProbeCounts:" + mLinkProbeExperimentProbeCounts); 2770 2771 pw.println("mNetworkSelectionExperimentPairNumChoicesCounts:" 2772 + mNetworkSelectionExperimentPairNumChoicesCounts); 2773 pw.println("mLinkProbeStaEventCount:" + mLinkProbeStaEventCount); 2774 2775 pw.println("mWifiNetworkRequestApiLog:\n" + mWifiNetworkRequestApiLog); 2776 pw.println("mWifiNetworkRequestApiMatchSizeHistogram:\n" 2777 + mWifiNetworkRequestApiMatchSizeHistogram); 2778 pw.println("mWifiNetworkSuggestionApiLog:\n" + mWifiNetworkSuggestionApiLog); 2779 pw.println("mWifiNetworkSuggestionApiMatchSizeHistogram:\n" 2780 + mWifiNetworkRequestApiMatchSizeHistogram); 2781 pw.println("mNetworkIdToNominatorId:\n" + mNetworkIdToNominatorId); 2782 pw.println("mWifiLockStats:\n" + mWifiLockStats); 2783 pw.println("mWifiLockHighPerfAcqDurationSecHistogram:\n" 2784 + mWifiLockHighPerfAcqDurationSecHistogram); 2785 pw.println("mWifiLockLowLatencyAcqDurationSecHistogram:\n" 2786 + mWifiLockLowLatencyAcqDurationSecHistogram); 2787 pw.println("mWifiLockHighPerfActiveSessionDurationSecHistogram:\n" 2788 + mWifiLockHighPerfActiveSessionDurationSecHistogram); 2789 pw.println("mWifiLockLowLatencyActiveSessionDurationSecHistogram:\n" 2790 + mWifiLockLowLatencyActiveSessionDurationSecHistogram); 2791 pw.println("mWifiToggleStats:\n" + mWifiToggleStats); 2792 pw.println("mWifiLogProto.numAddOrUpdateNetworkCalls=" 2793 + mWifiLogProto.numAddOrUpdateNetworkCalls); 2794 pw.println("mWifiLogProto.numEnableNetworkCalls=" 2795 + mWifiLogProto.numEnableNetworkCalls); 2796 } 2797 } 2798 } 2799 printWifiUsabilityStatsEntry(PrintWriter pw, WifiUsabilityStatsEntry entry)2800 private void printWifiUsabilityStatsEntry(PrintWriter pw, WifiUsabilityStatsEntry entry) { 2801 StringBuilder line = new StringBuilder(); 2802 line.append("timestamp_ms=" + entry.timeStampMs); 2803 line.append(",rssi=" + entry.rssi); 2804 line.append(",link_speed_mbps=" + entry.linkSpeedMbps); 2805 line.append(",total_tx_success=" + entry.totalTxSuccess); 2806 line.append(",total_tx_retries=" + entry.totalTxRetries); 2807 line.append(",total_tx_bad=" + entry.totalTxBad); 2808 line.append(",total_rx_success=" + entry.totalRxSuccess); 2809 line.append(",total_radio_on_time_ms=" + entry.totalRadioOnTimeMs); 2810 line.append(",total_radio_tx_time_ms=" + entry.totalRadioTxTimeMs); 2811 line.append(",total_radio_rx_time_ms=" + entry.totalRadioRxTimeMs); 2812 line.append(",total_scan_time_ms=" + entry.totalScanTimeMs); 2813 line.append(",total_nan_scan_time_ms=" + entry.totalNanScanTimeMs); 2814 line.append(",total_background_scan_time_ms=" + entry.totalBackgroundScanTimeMs); 2815 line.append(",total_roam_scan_time_ms=" + entry.totalRoamScanTimeMs); 2816 line.append(",total_pno_scan_time_ms=" + entry.totalPnoScanTimeMs); 2817 line.append(",total_hotspot_2_scan_time_ms=" + entry.totalHotspot2ScanTimeMs); 2818 line.append(",wifi_score=" + entry.wifiScore); 2819 line.append(",wifi_usability_score=" + entry.wifiUsabilityScore); 2820 line.append(",seq_num_to_framework=" + entry.seqNumToFramework); 2821 line.append(",prediction_horizon_sec=" + entry.predictionHorizonSec); 2822 line.append(",total_cca_busy_freq_time_ms=" + entry.totalCcaBusyFreqTimeMs); 2823 line.append(",total_radio_on_freq_time_ms=" + entry.totalRadioOnFreqTimeMs); 2824 line.append(",total_beacon_rx=" + entry.totalBeaconRx); 2825 line.append(",probe_status_since_last_update=" + entry.probeStatusSinceLastUpdate); 2826 line.append(",probe_elapsed_time_ms_since_last_update=" 2827 + entry.probeElapsedTimeSinceLastUpdateMs); 2828 line.append(",probe_mcs_rate_since_last_update=" + entry.probeMcsRateSinceLastUpdate); 2829 line.append(",rx_link_speed_mbps=" + entry.rxLinkSpeedMbps); 2830 line.append(",seq_num_inside_framework=" + entry.seqNumInsideFramework); 2831 line.append(",is_same_bssid_and_freq=" + entry.isSameBssidAndFreq); 2832 line.append(",cellular_data_network_type=" + entry.cellularDataNetworkType); 2833 line.append(",cellular_signal_strength_dbm=" + entry.cellularSignalStrengthDbm); 2834 line.append(",cellular_signal_strength_db=" + entry.cellularSignalStrengthDb); 2835 line.append(",is_same_registered_cell=" + entry.isSameRegisteredCell); 2836 line.append(",device_mobility_state=" + entry.deviceMobilityState); 2837 pw.println(line.toString()); 2838 } 2839 printDeviceMobilityStatePnoScanStats(PrintWriter pw, DeviceMobilityStatePnoScanStats stats)2840 private void printDeviceMobilityStatePnoScanStats(PrintWriter pw, 2841 DeviceMobilityStatePnoScanStats stats) { 2842 StringBuilder line = new StringBuilder(); 2843 line.append("device_mobility_state=" + stats.deviceMobilityState); 2844 line.append(",num_times_entered_state=" + stats.numTimesEnteredState); 2845 line.append(",total_duration_ms=" + stats.totalDurationMs); 2846 line.append(",pno_duration_ms=" + stats.pnoDurationMs); 2847 pw.println(line.toString()); 2848 } 2849 2850 /** 2851 * Update various counts of saved network types 2852 * @param networks List of WifiConfigurations representing all saved networks, must not be null 2853 */ updateSavedNetworks(List<WifiConfiguration> networks)2854 public void updateSavedNetworks(List<WifiConfiguration> networks) { 2855 synchronized (mLock) { 2856 mWifiLogProto.numSavedNetworks = networks.size(); 2857 mWifiLogProto.numOpenNetworks = 0; 2858 mWifiLogProto.numLegacyPersonalNetworks = 0; 2859 mWifiLogProto.numLegacyEnterpriseNetworks = 0; 2860 mWifiLogProto.numEnhancedOpenNetworks = 0; 2861 mWifiLogProto.numWpa3PersonalNetworks = 0; 2862 mWifiLogProto.numWpa3EnterpriseNetworks = 0; 2863 mWifiLogProto.numNetworksAddedByUser = 0; 2864 mWifiLogProto.numNetworksAddedByApps = 0; 2865 mWifiLogProto.numHiddenNetworks = 0; 2866 mWifiLogProto.numPasspointNetworks = 0; 2867 for (WifiConfiguration config : networks) { 2868 if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) { 2869 mWifiLogProto.numOpenNetworks++; 2870 } else if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE)) { 2871 mWifiLogProto.numEnhancedOpenNetworks++; 2872 } else if (config.isEnterprise()) { 2873 if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SUITE_B_192)) { 2874 mWifiLogProto.numWpa3EnterpriseNetworks++; 2875 } else { 2876 mWifiLogProto.numLegacyEnterpriseNetworks++; 2877 } 2878 } else { 2879 if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) { 2880 mWifiLogProto.numWpa3PersonalNetworks++; 2881 } else { 2882 mWifiLogProto.numLegacyPersonalNetworks++; 2883 } 2884 } 2885 if (config.selfAdded) { 2886 mWifiLogProto.numNetworksAddedByUser++; 2887 } else { 2888 mWifiLogProto.numNetworksAddedByApps++; 2889 } 2890 if (config.hiddenSSID) { 2891 mWifiLogProto.numHiddenNetworks++; 2892 } 2893 if (config.isPasspoint()) { 2894 mWifiLogProto.numPasspointNetworks++; 2895 } 2896 if (config.macRandomizationSetting == WifiConfiguration.RANDOMIZATION_PERSISTENT) { 2897 mWifiLogProto.numSavedNetworksWithMacRandomization++; 2898 } 2899 } 2900 } 2901 } 2902 2903 /** 2904 * Update metrics for saved Passpoint profiles. 2905 * 2906 * @param numSavedProfiles The number of saved Passpoint profiles 2907 * @param numConnectedProfiles The number of saved Passpoint profiles that have ever resulted 2908 * in a successful network connection 2909 */ updateSavedPasspointProfiles(int numSavedProfiles, int numConnectedProfiles)2910 public void updateSavedPasspointProfiles(int numSavedProfiles, int numConnectedProfiles) { 2911 synchronized (mLock) { 2912 mWifiLogProto.numPasspointProviders = numSavedProfiles; 2913 mWifiLogProto.numPasspointProvidersSuccessfullyConnected = numConnectedProfiles; 2914 } 2915 } 2916 2917 /** 2918 * Update number of times for type of saved Passpoint profile. 2919 * 2920 * @param providers Passpoint providers installed on the device. 2921 */ updateSavedPasspointProfilesInfo( Map<String, PasspointProvider> providers)2922 public void updateSavedPasspointProfilesInfo( 2923 Map<String, PasspointProvider> providers) { 2924 int passpointType; 2925 int eapType; 2926 PasspointConfiguration config; 2927 synchronized (mLock) { 2928 mInstalledPasspointProfileTypeForR1.clear(); 2929 mInstalledPasspointProfileTypeForR2.clear(); 2930 for (Map.Entry<String, PasspointProvider> entry : providers.entrySet()) { 2931 config = entry.getValue().getConfig(); 2932 if (config.getCredential().getUserCredential() != null) { 2933 eapType = EAPConstants.EAP_TTLS; 2934 } else if (config.getCredential().getCertCredential() != null) { 2935 eapType = EAPConstants.EAP_TLS; 2936 } else if (config.getCredential().getSimCredential() != null) { 2937 eapType = config.getCredential().getSimCredential().getEapType(); 2938 } else { 2939 eapType = -1; 2940 } 2941 switch (eapType) { 2942 case EAPConstants.EAP_TLS: 2943 passpointType = WifiMetricsProto.PasspointProfileTypeCount.TYPE_EAP_TLS; 2944 break; 2945 case EAPConstants.EAP_TTLS: 2946 passpointType = WifiMetricsProto.PasspointProfileTypeCount.TYPE_EAP_TTLS; 2947 break; 2948 case EAPConstants.EAP_SIM: 2949 passpointType = WifiMetricsProto.PasspointProfileTypeCount.TYPE_EAP_SIM; 2950 break; 2951 case EAPConstants.EAP_AKA: 2952 passpointType = WifiMetricsProto.PasspointProfileTypeCount.TYPE_EAP_AKA; 2953 break; 2954 case EAPConstants.EAP_AKA_PRIME: 2955 passpointType = 2956 WifiMetricsProto.PasspointProfileTypeCount.TYPE_EAP_AKA_PRIME; 2957 break; 2958 default: 2959 passpointType = WifiMetricsProto.PasspointProfileTypeCount.TYPE_UNKNOWN; 2960 2961 } 2962 if (config.validateForR2()) { 2963 mInstalledPasspointProfileTypeForR2.increment(passpointType); 2964 } else { 2965 mInstalledPasspointProfileTypeForR1.increment(passpointType); 2966 } 2967 } 2968 } 2969 } 2970 2971 /** 2972 * Put all metrics that were being tracked separately into mWifiLogProto 2973 */ consolidateProto()2974 private void consolidateProto() { 2975 List<WifiMetricsProto.RssiPollCount> rssis = new ArrayList<>(); 2976 synchronized (mLock) { 2977 int connectionEventCount = mConnectionEventList.size(); 2978 // Exclude the current active un-ended connection event 2979 if (mCurrentConnectionEvent != null) { 2980 connectionEventCount--; 2981 } 2982 mWifiLogProto.connectionEvent = 2983 new WifiMetricsProto.ConnectionEvent[connectionEventCount]; 2984 for (int i = 0; i < connectionEventCount; i++) { 2985 mWifiLogProto.connectionEvent[i] = mConnectionEventList.get(i).mConnectionEvent; 2986 } 2987 2988 //Convert the SparseIntArray of scanReturnEntry integers into ScanReturnEntry proto list 2989 mWifiLogProto.scanReturnEntries = 2990 new WifiMetricsProto.WifiLog.ScanReturnEntry[mScanReturnEntries.size()]; 2991 for (int i = 0; i < mScanReturnEntries.size(); i++) { 2992 mWifiLogProto.scanReturnEntries[i] = new WifiMetricsProto.WifiLog.ScanReturnEntry(); 2993 mWifiLogProto.scanReturnEntries[i].scanReturnCode = mScanReturnEntries.keyAt(i); 2994 mWifiLogProto.scanReturnEntries[i].scanResultsCount = mScanReturnEntries.valueAt(i); 2995 } 2996 2997 // Convert the SparseIntArray of systemStateEntry into WifiSystemStateEntry proto list 2998 // This one is slightly more complex, as the Sparse are indexed with: 2999 // key: wifiState * 2 + isScreenOn, value: wifiStateCount 3000 mWifiLogProto.wifiSystemStateEntries = 3001 new WifiMetricsProto.WifiLog 3002 .WifiSystemStateEntry[mWifiSystemStateEntries.size()]; 3003 for (int i = 0; i < mWifiSystemStateEntries.size(); i++) { 3004 mWifiLogProto.wifiSystemStateEntries[i] = 3005 new WifiMetricsProto.WifiLog.WifiSystemStateEntry(); 3006 mWifiLogProto.wifiSystemStateEntries[i].wifiState = 3007 mWifiSystemStateEntries.keyAt(i) / 2; 3008 mWifiLogProto.wifiSystemStateEntries[i].wifiStateCount = 3009 mWifiSystemStateEntries.valueAt(i); 3010 mWifiLogProto.wifiSystemStateEntries[i].isScreenOn = 3011 (mWifiSystemStateEntries.keyAt(i) % 2) > 0; 3012 } 3013 mWifiLogProto.recordDurationSec = (int) ((mClock.getElapsedSinceBootMillis() / 1000) 3014 - mRecordStartTimeSec); 3015 3016 /** 3017 * Convert the SparseIntArrays of RSSI poll rssi, counts, and frequency to the 3018 * proto's repeated IntKeyVal array. 3019 */ 3020 for (Map.Entry<Integer, SparseIntArray> entry : mRssiPollCountsMap.entrySet()) { 3021 int frequency = entry.getKey(); 3022 SparseIntArray histogram = entry.getValue(); 3023 for (int i = 0; i < histogram.size(); i++) { 3024 WifiMetricsProto.RssiPollCount keyVal = new WifiMetricsProto.RssiPollCount(); 3025 keyVal.rssi = histogram.keyAt(i); 3026 keyVal.count = histogram.valueAt(i); 3027 keyVal.frequency = frequency; 3028 rssis.add(keyVal); 3029 } 3030 } 3031 mWifiLogProto.rssiPollRssiCount = rssis.toArray(mWifiLogProto.rssiPollRssiCount); 3032 3033 /** 3034 * Convert the SparseIntArray of RSSI delta rssi's and counts to the proto's repeated 3035 * IntKeyVal array. 3036 */ 3037 mWifiLogProto.rssiPollDeltaCount = 3038 new WifiMetricsProto.RssiPollCount[mRssiDeltaCounts.size()]; 3039 for (int i = 0; i < mRssiDeltaCounts.size(); i++) { 3040 mWifiLogProto.rssiPollDeltaCount[i] = new WifiMetricsProto.RssiPollCount(); 3041 mWifiLogProto.rssiPollDeltaCount[i].rssi = mRssiDeltaCounts.keyAt(i); 3042 mWifiLogProto.rssiPollDeltaCount[i].count = mRssiDeltaCounts.valueAt(i); 3043 } 3044 3045 /** 3046 * Add LinkSpeedCount objects from mLinkSpeedCounts to proto. 3047 */ 3048 mWifiLogProto.linkSpeedCounts = 3049 new WifiMetricsProto.LinkSpeedCount[mLinkSpeedCounts.size()]; 3050 for (int i = 0; i < mLinkSpeedCounts.size(); i++) { 3051 mWifiLogProto.linkSpeedCounts[i] = mLinkSpeedCounts.valueAt(i); 3052 } 3053 3054 /** 3055 * Convert the SparseIntArray of alert reasons and counts to the proto's repeated 3056 * IntKeyVal array. 3057 */ 3058 mWifiLogProto.alertReasonCount = 3059 new WifiMetricsProto.AlertReasonCount[mWifiAlertReasonCounts.size()]; 3060 for (int i = 0; i < mWifiAlertReasonCounts.size(); i++) { 3061 mWifiLogProto.alertReasonCount[i] = new WifiMetricsProto.AlertReasonCount(); 3062 mWifiLogProto.alertReasonCount[i].reason = mWifiAlertReasonCounts.keyAt(i); 3063 mWifiLogProto.alertReasonCount[i].count = mWifiAlertReasonCounts.valueAt(i); 3064 } 3065 3066 /** 3067 * Convert the SparseIntArray of Wifi Score and counts to proto's repeated 3068 * IntKeyVal array. 3069 */ 3070 mWifiLogProto.wifiScoreCount = 3071 new WifiMetricsProto.WifiScoreCount[mWifiScoreCounts.size()]; 3072 for (int score = 0; score < mWifiScoreCounts.size(); score++) { 3073 mWifiLogProto.wifiScoreCount[score] = new WifiMetricsProto.WifiScoreCount(); 3074 mWifiLogProto.wifiScoreCount[score].score = mWifiScoreCounts.keyAt(score); 3075 mWifiLogProto.wifiScoreCount[score].count = mWifiScoreCounts.valueAt(score); 3076 } 3077 3078 /** 3079 * Convert the SparseIntArray of Wifi Usability Score and counts to proto's repeated 3080 * IntKeyVal array. 3081 */ 3082 mWifiLogProto.wifiUsabilityScoreCount = 3083 new WifiMetricsProto.WifiUsabilityScoreCount[mWifiUsabilityScoreCounts.size()]; 3084 for (int scoreIdx = 0; scoreIdx < mWifiUsabilityScoreCounts.size(); scoreIdx++) { 3085 mWifiLogProto.wifiUsabilityScoreCount[scoreIdx] = 3086 new WifiMetricsProto.WifiUsabilityScoreCount(); 3087 mWifiLogProto.wifiUsabilityScoreCount[scoreIdx].score = 3088 mWifiUsabilityScoreCounts.keyAt(scoreIdx); 3089 mWifiLogProto.wifiUsabilityScoreCount[scoreIdx].count = 3090 mWifiUsabilityScoreCounts.valueAt(scoreIdx); 3091 } 3092 3093 /** 3094 * Convert the SparseIntArray of SoftAp Return codes and counts to proto's repeated 3095 * IntKeyVal array. 3096 */ 3097 int codeCounts = mSoftApManagerReturnCodeCounts.size(); 3098 mWifiLogProto.softApReturnCode = new WifiMetricsProto.SoftApReturnCodeCount[codeCounts]; 3099 for (int sapCode = 0; sapCode < codeCounts; sapCode++) { 3100 mWifiLogProto.softApReturnCode[sapCode] = 3101 new WifiMetricsProto.SoftApReturnCodeCount(); 3102 mWifiLogProto.softApReturnCode[sapCode].startResult = 3103 mSoftApManagerReturnCodeCounts.keyAt(sapCode); 3104 mWifiLogProto.softApReturnCode[sapCode].count = 3105 mSoftApManagerReturnCodeCounts.valueAt(sapCode); 3106 } 3107 3108 /** 3109 * Convert StaEventList to array of StaEvents 3110 */ 3111 mWifiLogProto.staEventList = new StaEvent[mStaEventList.size()]; 3112 for (int i = 0; i < mStaEventList.size(); i++) { 3113 mWifiLogProto.staEventList[i] = mStaEventList.get(i).staEvent; 3114 } 3115 mWifiLogProto.totalSsidsInScanHistogram = 3116 makeNumConnectableNetworksBucketArray(mTotalSsidsInScanHistogram); 3117 mWifiLogProto.totalBssidsInScanHistogram = 3118 makeNumConnectableNetworksBucketArray(mTotalBssidsInScanHistogram); 3119 mWifiLogProto.availableOpenSsidsInScanHistogram = 3120 makeNumConnectableNetworksBucketArray(mAvailableOpenSsidsInScanHistogram); 3121 mWifiLogProto.availableOpenBssidsInScanHistogram = 3122 makeNumConnectableNetworksBucketArray(mAvailableOpenBssidsInScanHistogram); 3123 mWifiLogProto.availableSavedSsidsInScanHistogram = 3124 makeNumConnectableNetworksBucketArray(mAvailableSavedSsidsInScanHistogram); 3125 mWifiLogProto.availableSavedBssidsInScanHistogram = 3126 makeNumConnectableNetworksBucketArray(mAvailableSavedBssidsInScanHistogram); 3127 mWifiLogProto.availableOpenOrSavedSsidsInScanHistogram = 3128 makeNumConnectableNetworksBucketArray( 3129 mAvailableOpenOrSavedSsidsInScanHistogram); 3130 mWifiLogProto.availableOpenOrSavedBssidsInScanHistogram = 3131 makeNumConnectableNetworksBucketArray( 3132 mAvailableOpenOrSavedBssidsInScanHistogram); 3133 mWifiLogProto.availableSavedPasspointProviderProfilesInScanHistogram = 3134 makeNumConnectableNetworksBucketArray( 3135 mAvailableSavedPasspointProviderProfilesInScanHistogram); 3136 mWifiLogProto.availableSavedPasspointProviderBssidsInScanHistogram = 3137 makeNumConnectableNetworksBucketArray( 3138 mAvailableSavedPasspointProviderBssidsInScanHistogram); 3139 mWifiLogProto.wifiAwareLog = mWifiAwareMetrics.consolidateProto(); 3140 mWifiLogProto.wifiRttLog = mRttMetrics.consolidateProto(); 3141 3142 mWifiLogProto.pnoScanMetrics = mPnoScanMetrics; 3143 mWifiLogProto.wifiLinkLayerUsageStats = mWifiLinkLayerUsageStats; 3144 3145 /** 3146 * Convert the SparseIntArray of "Connect to Network" notification types and counts to 3147 * proto's repeated IntKeyVal array. 3148 */ 3149 ConnectToNetworkNotificationAndActionCount[] notificationCountArray = 3150 new ConnectToNetworkNotificationAndActionCount[ 3151 mConnectToNetworkNotificationCount.size()]; 3152 for (int i = 0; i < mConnectToNetworkNotificationCount.size(); i++) { 3153 ConnectToNetworkNotificationAndActionCount keyVal = 3154 new ConnectToNetworkNotificationAndActionCount(); 3155 keyVal.notification = mConnectToNetworkNotificationCount.keyAt(i); 3156 keyVal.recommender = 3157 ConnectToNetworkNotificationAndActionCount.RECOMMENDER_OPEN; 3158 keyVal.count = mConnectToNetworkNotificationCount.valueAt(i); 3159 notificationCountArray[i] = keyVal; 3160 } 3161 mWifiLogProto.connectToNetworkNotificationCount = notificationCountArray; 3162 3163 /** 3164 * Convert the SparseIntArray of "Connect to Network" notification types and counts to 3165 * proto's repeated IntKeyVal array. 3166 */ 3167 ConnectToNetworkNotificationAndActionCount[] notificationActionCountArray = 3168 new ConnectToNetworkNotificationAndActionCount[ 3169 mConnectToNetworkNotificationActionCount.size()]; 3170 for (int i = 0; i < mConnectToNetworkNotificationActionCount.size(); i++) { 3171 ConnectToNetworkNotificationAndActionCount keyVal = 3172 new ConnectToNetworkNotificationAndActionCount(); 3173 int key = mConnectToNetworkNotificationActionCount.keyAt(i); 3174 keyVal.notification = key / CONNECT_TO_NETWORK_NOTIFICATION_ACTION_KEY_MULTIPLIER; 3175 keyVal.action = key % CONNECT_TO_NETWORK_NOTIFICATION_ACTION_KEY_MULTIPLIER; 3176 keyVal.recommender = 3177 ConnectToNetworkNotificationAndActionCount.RECOMMENDER_OPEN; 3178 keyVal.count = mConnectToNetworkNotificationActionCount.valueAt(i); 3179 notificationActionCountArray[i] = keyVal; 3180 } 3181 3182 mWifiLogProto.installedPasspointProfileTypeForR1 = 3183 convertPasspointProfilesToProto(mInstalledPasspointProfileTypeForR1); 3184 mWifiLogProto.installedPasspointProfileTypeForR2 = 3185 convertPasspointProfilesToProto(mInstalledPasspointProfileTypeForR2); 3186 3187 mWifiLogProto.connectToNetworkNotificationActionCount = notificationActionCountArray; 3188 3189 mWifiLogProto.openNetworkRecommenderBlacklistSize = 3190 mOpenNetworkRecommenderBlacklistSize; 3191 mWifiLogProto.isWifiNetworksAvailableNotificationOn = 3192 mIsWifiNetworksAvailableNotificationOn; 3193 mWifiLogProto.numOpenNetworkRecommendationUpdates = 3194 mNumOpenNetworkRecommendationUpdates; 3195 mWifiLogProto.numOpenNetworkConnectMessageFailedToSend = 3196 mNumOpenNetworkConnectMessageFailedToSend; 3197 3198 mWifiLogProto.observedHotspotR1ApsInScanHistogram = 3199 makeNumConnectableNetworksBucketArray(mObservedHotspotR1ApInScanHistogram); 3200 mWifiLogProto.observedHotspotR2ApsInScanHistogram = 3201 makeNumConnectableNetworksBucketArray(mObservedHotspotR2ApInScanHistogram); 3202 mWifiLogProto.observedHotspotR1EssInScanHistogram = 3203 makeNumConnectableNetworksBucketArray(mObservedHotspotR1EssInScanHistogram); 3204 mWifiLogProto.observedHotspotR2EssInScanHistogram = 3205 makeNumConnectableNetworksBucketArray(mObservedHotspotR2EssInScanHistogram); 3206 mWifiLogProto.observedHotspotR1ApsPerEssInScanHistogram = 3207 makeNumConnectableNetworksBucketArray( 3208 mObservedHotspotR1ApsPerEssInScanHistogram); 3209 mWifiLogProto.observedHotspotR2ApsPerEssInScanHistogram = 3210 makeNumConnectableNetworksBucketArray( 3211 mObservedHotspotR2ApsPerEssInScanHistogram); 3212 3213 mWifiLogProto.observed80211McSupportingApsInScanHistogram = 3214 makeNumConnectableNetworksBucketArray(mObserved80211mcApInScanHistogram); 3215 3216 if (mSoftApEventListTethered.size() > 0) { 3217 mWifiLogProto.softApConnectedClientsEventsTethered = 3218 mSoftApEventListTethered.toArray( 3219 mWifiLogProto.softApConnectedClientsEventsTethered); 3220 } 3221 if (mSoftApEventListLocalOnly.size() > 0) { 3222 mWifiLogProto.softApConnectedClientsEventsLocalOnly = 3223 mSoftApEventListLocalOnly.toArray( 3224 mWifiLogProto.softApConnectedClientsEventsLocalOnly); 3225 } 3226 3227 mWifiLogProto.wpsMetrics = mWpsMetrics; 3228 mWifiLogProto.wifiPowerStats = mWifiPowerMetrics.buildProto(); 3229 mWifiLogProto.wifiRadioUsage = mWifiPowerMetrics.buildWifiRadioUsageProto(); 3230 mWifiLogProto.wifiWakeStats = mWifiWakeMetrics.buildProto(); 3231 mWifiLogProto.isMacRandomizationOn = mIsMacRandomizationOn; 3232 mWifiLogProto.experimentValues = mExperimentValues; 3233 mWifiLogProto.wifiIsUnusableEventList = 3234 new WifiIsUnusableEvent[mWifiIsUnusableList.size()]; 3235 for (int i = 0; i < mWifiIsUnusableList.size(); i++) { 3236 mWifiLogProto.wifiIsUnusableEventList[i] = mWifiIsUnusableList.get(i).event; 3237 } 3238 mWifiLogProto.hardwareRevision = SystemProperties.get("ro.boot.revision", ""); 3239 3240 // Postprocessing on WifiUsabilityStats to upload an equal number of LABEL_GOOD and 3241 // LABEL_BAD WifiUsabilityStats 3242 final int numUsabilityStats = Math.min( 3243 Math.min(mWifiUsabilityStatsListBad.size(), 3244 mWifiUsabilityStatsListGood.size()), 3245 MAX_WIFI_USABILITY_STATS_PER_TYPE_TO_UPLOAD); 3246 LinkedList<WifiUsabilityStats> usabilityStatsGoodCopy = 3247 new LinkedList<>(mWifiUsabilityStatsListGood); 3248 LinkedList<WifiUsabilityStats> usabilityStatsBadCopy = 3249 new LinkedList<>(mWifiUsabilityStatsListBad); 3250 mWifiLogProto.wifiUsabilityStatsList = new WifiUsabilityStats[numUsabilityStats * 2]; 3251 for (int i = 0; i < numUsabilityStats; i++) { 3252 mWifiLogProto.wifiUsabilityStatsList[2 * i] = usabilityStatsGoodCopy.remove( 3253 mRand.nextInt(usabilityStatsGoodCopy.size())); 3254 mWifiLogProto.wifiUsabilityStatsList[2 * i + 1] = usabilityStatsBadCopy.remove( 3255 mRand.nextInt(usabilityStatsBadCopy.size())); 3256 } 3257 mWifiLogProto.mobilityStatePnoStatsList = 3258 new DeviceMobilityStatePnoScanStats[mMobilityStatePnoStatsMap.size()]; 3259 for (int i = 0; i < mMobilityStatePnoStatsMap.size(); i++) { 3260 mWifiLogProto.mobilityStatePnoStatsList[i] = mMobilityStatePnoStatsMap.valueAt(i); 3261 } 3262 mWifiLogProto.wifiP2PStats = mWifiP2pMetrics.consolidateProto(); 3263 mWifiLogProto.wifiDppLog = mDppMetrics.consolidateProto(); 3264 mWifiLogProto.wifiConfigStoreIo = new WifiMetricsProto.WifiConfigStoreIO(); 3265 mWifiLogProto.wifiConfigStoreIo.readDurations = 3266 makeWifiConfigStoreIODurationBucketArray(mWifiConfigStoreReadDurationHistogram); 3267 mWifiLogProto.wifiConfigStoreIo.writeDurations = 3268 makeWifiConfigStoreIODurationBucketArray( 3269 mWifiConfigStoreWriteDurationHistogram); 3270 3271 LinkProbeStats linkProbeStats = new LinkProbeStats(); 3272 linkProbeStats.successRssiCounts = mLinkProbeSuccessRssiCounts.toProto(); 3273 linkProbeStats.failureRssiCounts = mLinkProbeFailureRssiCounts.toProto(); 3274 linkProbeStats.successLinkSpeedCounts = mLinkProbeSuccessLinkSpeedCounts.toProto(); 3275 linkProbeStats.failureLinkSpeedCounts = mLinkProbeFailureLinkSpeedCounts.toProto(); 3276 linkProbeStats.successSecondsSinceLastTxSuccessHistogram = 3277 mLinkProbeSuccessSecondsSinceLastTxSuccessHistogram.toProto(); 3278 linkProbeStats.failureSecondsSinceLastTxSuccessHistogram = 3279 mLinkProbeFailureSecondsSinceLastTxSuccessHistogram.toProto(); 3280 linkProbeStats.successElapsedTimeMsHistogram = 3281 mLinkProbeSuccessElapsedTimeMsHistogram.toProto(); 3282 linkProbeStats.failureReasonCounts = mLinkProbeFailureReasonCounts.toProto( 3283 LinkProbeFailureReasonCount.class, 3284 (reason, count) -> { 3285 LinkProbeFailureReasonCount c = new LinkProbeFailureReasonCount(); 3286 c.failureReason = linkProbeFailureReasonToProto(reason); 3287 c.count = count; 3288 return c; 3289 }); 3290 linkProbeStats.experimentProbeCounts = mLinkProbeExperimentProbeCounts.toProto( 3291 ExperimentProbeCounts.class, 3292 (experimentId, probeCount) -> { 3293 ExperimentProbeCounts c = new ExperimentProbeCounts(); 3294 c.experimentId = experimentId; 3295 c.probeCount = probeCount; 3296 return c; 3297 }); 3298 mWifiLogProto.linkProbeStats = linkProbeStats; 3299 3300 mWifiLogProto.networkSelectionExperimentDecisionsList = 3301 makeNetworkSelectionExperimentDecisionsList(); 3302 3303 mWifiNetworkRequestApiLog.networkMatchSizeHistogram = 3304 mWifiNetworkRequestApiMatchSizeHistogram.toProto(); 3305 mWifiLogProto.wifiNetworkRequestApiLog = mWifiNetworkRequestApiLog; 3306 3307 mWifiNetworkSuggestionApiLog.networkListSizeHistogram = 3308 mWifiNetworkSuggestionApiListSizeHistogram.toProto(); 3309 mWifiLogProto.wifiNetworkSuggestionApiLog = mWifiNetworkSuggestionApiLog; 3310 3311 mWifiLockStats.highPerfLockAcqDurationSecHistogram = 3312 mWifiLockHighPerfAcqDurationSecHistogram.toProto(); 3313 3314 mWifiLockStats.lowLatencyLockAcqDurationSecHistogram = 3315 mWifiLockLowLatencyAcqDurationSecHistogram.toProto(); 3316 3317 mWifiLockStats.highPerfActiveSessionDurationSecHistogram = 3318 mWifiLockHighPerfActiveSessionDurationSecHistogram.toProto(); 3319 3320 mWifiLockStats.lowLatencyActiveSessionDurationSecHistogram = 3321 mWifiLockLowLatencyActiveSessionDurationSecHistogram.toProto(); 3322 3323 mWifiLogProto.wifiLockStats = mWifiLockStats; 3324 mWifiLogProto.wifiToggleStats = mWifiToggleStats; 3325 3326 /** 3327 * Convert the SparseIntArray of passpoint provision failure code 3328 * and counts to the proto's repeated IntKeyVal array. 3329 */ 3330 mWifiLogProto.passpointProvisionStats = new PasspointProvisionStats(); 3331 mWifiLogProto.passpointProvisionStats.numProvisionSuccess = mNumProvisionSuccess; 3332 mWifiLogProto.passpointProvisionStats.provisionFailureCount = 3333 mPasspointProvisionFailureCounts.toProto(ProvisionFailureCount.class, 3334 (key, count) -> { 3335 ProvisionFailureCount entry = new ProvisionFailureCount(); 3336 entry.failureCode = key; 3337 entry.count = count; 3338 return entry; 3339 }); 3340 } 3341 } 3342 linkProbeFailureReasonToProto(@ifiNative.SendMgmtFrameError int reason)3343 private static int linkProbeFailureReasonToProto(@WifiNative.SendMgmtFrameError int reason) { 3344 switch (reason) { 3345 case WifiNative.SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED: 3346 return LinkProbeStats.LINK_PROBE_FAILURE_REASON_MCS_UNSUPPORTED; 3347 case WifiNative.SEND_MGMT_FRAME_ERROR_NO_ACK: 3348 return LinkProbeStats.LINK_PROBE_FAILURE_REASON_NO_ACK; 3349 case WifiNative.SEND_MGMT_FRAME_ERROR_TIMEOUT: 3350 return LinkProbeStats.LINK_PROBE_FAILURE_REASON_TIMEOUT; 3351 case WifiNative.SEND_MGMT_FRAME_ERROR_ALREADY_STARTED: 3352 return LinkProbeStats.LINK_PROBE_FAILURE_REASON_ALREADY_STARTED; 3353 default: 3354 return LinkProbeStats.LINK_PROBE_FAILURE_REASON_UNKNOWN; 3355 } 3356 } 3357 makeNetworkSelectionExperimentDecisionsList()3358 private NetworkSelectionExperimentDecisions[] makeNetworkSelectionExperimentDecisionsList() { 3359 NetworkSelectionExperimentDecisions[] results = new NetworkSelectionExperimentDecisions[ 3360 mNetworkSelectionExperimentPairNumChoicesCounts.size()]; 3361 int i = 0; 3362 for (Map.Entry<Pair<Integer, Integer>, NetworkSelectionExperimentResults> entry : 3363 mNetworkSelectionExperimentPairNumChoicesCounts.entrySet()) { 3364 NetworkSelectionExperimentDecisions result = new NetworkSelectionExperimentDecisions(); 3365 result.experiment1Id = entry.getKey().first; 3366 result.experiment2Id = entry.getKey().second; 3367 result.sameSelectionNumChoicesCounter = 3368 entry.getValue().sameSelectionNumChoicesCounter.toProto(); 3369 result.differentSelectionNumChoicesCounter = 3370 entry.getValue().differentSelectionNumChoicesCounter.toProto(); 3371 results[i] = result; 3372 i++; 3373 } 3374 return results; 3375 } 3376 3377 /** Sets the scoring experiment id to current value */ consolidateScoringParams()3378 private void consolidateScoringParams() { 3379 synchronized (mLock) { 3380 if (mScoringParams != null) { 3381 int experimentIdentifier = mScoringParams.getExperimentIdentifier(); 3382 if (experimentIdentifier == 0) { 3383 mWifiLogProto.scoreExperimentId = ""; 3384 } else { 3385 mWifiLogProto.scoreExperimentId = "x" + experimentIdentifier; 3386 } 3387 } 3388 } 3389 } 3390 makeNumConnectableNetworksBucketArray( SparseIntArray sia)3391 private WifiMetricsProto.NumConnectableNetworksBucket[] makeNumConnectableNetworksBucketArray( 3392 SparseIntArray sia) { 3393 WifiMetricsProto.NumConnectableNetworksBucket[] array = 3394 new WifiMetricsProto.NumConnectableNetworksBucket[sia.size()]; 3395 for (int i = 0; i < sia.size(); i++) { 3396 WifiMetricsProto.NumConnectableNetworksBucket keyVal = 3397 new WifiMetricsProto.NumConnectableNetworksBucket(); 3398 keyVal.numConnectableNetworks = sia.keyAt(i); 3399 keyVal.count = sia.valueAt(i); 3400 array[i] = keyVal; 3401 } 3402 return array; 3403 } 3404 3405 private WifiMetricsProto.WifiConfigStoreIO.DurationBucket[] makeWifiConfigStoreIODurationBucketArray(SparseIntArray sia)3406 makeWifiConfigStoreIODurationBucketArray(SparseIntArray sia) { 3407 MetricsUtils.GenericBucket[] genericBuckets = 3408 MetricsUtils.linearHistogramToGenericBuckets(sia, 3409 WIFI_CONFIG_STORE_IO_DURATION_BUCKET_RANGES_MS); 3410 WifiMetricsProto.WifiConfigStoreIO.DurationBucket[] array = 3411 new WifiMetricsProto.WifiConfigStoreIO.DurationBucket[genericBuckets.length]; 3412 try { 3413 for (int i = 0; i < genericBuckets.length; i++) { 3414 array[i] = new WifiMetricsProto.WifiConfigStoreIO.DurationBucket(); 3415 array[i].rangeStartMs = toIntExact(genericBuckets[i].start); 3416 array[i].rangeEndMs = toIntExact(genericBuckets[i].end); 3417 array[i].count = genericBuckets[i].count; 3418 } 3419 } catch (ArithmeticException e) { 3420 // Return empty array on any overflow errors. 3421 array = new WifiMetricsProto.WifiConfigStoreIO.DurationBucket[0]; 3422 } 3423 return array; 3424 } 3425 3426 /** 3427 * Clear all WifiMetrics, except for currentConnectionEvent and Open Network Notification 3428 * feature enabled state, blacklist size. 3429 */ clear()3430 private void clear() { 3431 synchronized (mLock) { 3432 loadSettings(); 3433 mConnectionEventList.clear(); 3434 if (mCurrentConnectionEvent != null) { 3435 mConnectionEventList.add(mCurrentConnectionEvent); 3436 } 3437 mScanReturnEntries.clear(); 3438 mWifiSystemStateEntries.clear(); 3439 mRecordStartTimeSec = mClock.getElapsedSinceBootMillis() / 1000; 3440 mRssiPollCountsMap.clear(); 3441 mRssiDeltaCounts.clear(); 3442 mLinkSpeedCounts.clear(); 3443 mWifiAlertReasonCounts.clear(); 3444 mWifiScoreCounts.clear(); 3445 mWifiUsabilityScoreCounts.clear(); 3446 mWifiLogProto.clear(); 3447 mScanResultRssiTimestampMillis = -1; 3448 mSoftApManagerReturnCodeCounts.clear(); 3449 mStaEventList.clear(); 3450 mWifiAwareMetrics.clear(); 3451 mRttMetrics.clear(); 3452 mTotalSsidsInScanHistogram.clear(); 3453 mTotalBssidsInScanHistogram.clear(); 3454 mAvailableOpenSsidsInScanHistogram.clear(); 3455 mAvailableOpenBssidsInScanHistogram.clear(); 3456 mAvailableSavedSsidsInScanHistogram.clear(); 3457 mAvailableSavedBssidsInScanHistogram.clear(); 3458 mAvailableOpenOrSavedSsidsInScanHistogram.clear(); 3459 mAvailableOpenOrSavedBssidsInScanHistogram.clear(); 3460 mAvailableSavedPasspointProviderProfilesInScanHistogram.clear(); 3461 mAvailableSavedPasspointProviderBssidsInScanHistogram.clear(); 3462 mPnoScanMetrics.clear(); 3463 mWifiLinkLayerUsageStats.clear(); 3464 mConnectToNetworkNotificationCount.clear(); 3465 mConnectToNetworkNotificationActionCount.clear(); 3466 mNumOpenNetworkRecommendationUpdates = 0; 3467 mNumOpenNetworkConnectMessageFailedToSend = 0; 3468 mObservedHotspotR1ApInScanHistogram.clear(); 3469 mObservedHotspotR2ApInScanHistogram.clear(); 3470 mObservedHotspotR1EssInScanHistogram.clear(); 3471 mObservedHotspotR2EssInScanHistogram.clear(); 3472 mObservedHotspotR1ApsPerEssInScanHistogram.clear(); 3473 mObservedHotspotR2ApsPerEssInScanHistogram.clear(); 3474 mSoftApEventListTethered.clear(); 3475 mSoftApEventListLocalOnly.clear(); 3476 mWpsMetrics.clear(); 3477 mWifiWakeMetrics.clear(); 3478 mObserved80211mcApInScanHistogram.clear(); 3479 mWifiIsUnusableList.clear(); 3480 mInstalledPasspointProfileTypeForR1.clear(); 3481 mInstalledPasspointProfileTypeForR2.clear(); 3482 mWifiUsabilityStatsListGood.clear(); 3483 mWifiUsabilityStatsListBad.clear(); 3484 mWifiUsabilityStatsEntriesList.clear(); 3485 mMobilityStatePnoStatsMap.clear(); 3486 mWifiP2pMetrics.clear(); 3487 mDppMetrics.clear(); 3488 mWifiUsabilityStatsCounter = 0; 3489 mLastBssid = null; 3490 mLastFrequency = -1; 3491 mSeqNumInsideFramework = 0; 3492 mLastWifiUsabilityScore = -1; 3493 mLastWifiUsabilityScoreNoReset = -1; 3494 mLastPredictionHorizonSec = -1; 3495 mLastPredictionHorizonSecNoReset = -1; 3496 mSeqNumToFramework = -1; 3497 mProbeStatusSinceLastUpdate = 3498 android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE; 3499 mProbeElapsedTimeSinceLastUpdateMs = -1; 3500 mProbeMcsRateSinceLastUpdate = -1; 3501 mScoreBreachLowTimeMillis = -1; 3502 mWifiConfigStoreReadDurationHistogram.clear(); 3503 mWifiConfigStoreWriteDurationHistogram.clear(); 3504 mLinkProbeSuccessRssiCounts.clear(); 3505 mLinkProbeFailureRssiCounts.clear(); 3506 mLinkProbeSuccessLinkSpeedCounts.clear(); 3507 mLinkProbeFailureLinkSpeedCounts.clear(); 3508 mLinkProbeSuccessSecondsSinceLastTxSuccessHistogram.clear(); 3509 mLinkProbeFailureSecondsSinceLastTxSuccessHistogram.clear(); 3510 mLinkProbeSuccessElapsedTimeMsHistogram.clear(); 3511 mLinkProbeFailureReasonCounts.clear(); 3512 mLinkProbeExperimentProbeCounts.clear(); 3513 mLinkProbeStaEventCount = 0; 3514 mNetworkSelectionExperimentPairNumChoicesCounts.clear(); 3515 mWifiNetworkSuggestionApiLog.clear(); 3516 mWifiNetworkSuggestionApiLog.clear(); 3517 mWifiNetworkRequestApiMatchSizeHistogram.clear(); 3518 mWifiNetworkSuggestionApiListSizeHistogram.clear(); 3519 mWifiLockHighPerfAcqDurationSecHistogram.clear(); 3520 mWifiLockLowLatencyAcqDurationSecHistogram.clear(); 3521 mWifiLockHighPerfActiveSessionDurationSecHistogram.clear(); 3522 mWifiLockLowLatencyActiveSessionDurationSecHistogram.clear(); 3523 mWifiLockStats.clear(); 3524 mWifiToggleStats.clear(); 3525 mPasspointProvisionFailureCounts.clear(); 3526 mNumProvisionSuccess = 0; 3527 } 3528 } 3529 3530 /** 3531 * Set screen state (On/Off) 3532 */ setScreenState(boolean screenOn)3533 public void setScreenState(boolean screenOn) { 3534 synchronized (mLock) { 3535 mScreenOn = screenOn; 3536 } 3537 } 3538 3539 /** 3540 * Set wifi state (WIFI_UNKNOWN, WIFI_DISABLED, WIFI_DISCONNECTED, WIFI_ASSOCIATED) 3541 */ setWifiState(int wifiState)3542 public void setWifiState(int wifiState) { 3543 synchronized (mLock) { 3544 mWifiState = wifiState; 3545 mWifiWins = (wifiState == WifiMetricsProto.WifiLog.WIFI_ASSOCIATED); 3546 mWifiWinsUsabilityScore = (wifiState == WifiMetricsProto.WifiLog.WIFI_ASSOCIATED); 3547 } 3548 } 3549 3550 /** 3551 * Message handler for interesting WifiMonitor messages. Generates StaEvents 3552 */ processMessage(Message msg)3553 private void processMessage(Message msg) { 3554 StaEvent event = new StaEvent(); 3555 boolean logEvent = true; 3556 switch (msg.what) { 3557 case WifiMonitor.ASSOCIATION_REJECTION_EVENT: 3558 event.type = StaEvent.TYPE_ASSOCIATION_REJECTION_EVENT; 3559 event.associationTimedOut = msg.arg1 > 0 ? true : false; 3560 event.status = msg.arg2; 3561 break; 3562 case WifiMonitor.AUTHENTICATION_FAILURE_EVENT: 3563 event.type = StaEvent.TYPE_AUTHENTICATION_FAILURE_EVENT; 3564 switch (msg.arg1) { 3565 case WifiManager.ERROR_AUTH_FAILURE_NONE: 3566 event.authFailureReason = StaEvent.AUTH_FAILURE_NONE; 3567 break; 3568 case WifiManager.ERROR_AUTH_FAILURE_TIMEOUT: 3569 event.authFailureReason = StaEvent.AUTH_FAILURE_TIMEOUT; 3570 break; 3571 case WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD: 3572 event.authFailureReason = StaEvent.AUTH_FAILURE_WRONG_PSWD; 3573 break; 3574 case WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE: 3575 event.authFailureReason = StaEvent.AUTH_FAILURE_EAP_FAILURE; 3576 break; 3577 default: 3578 break; 3579 } 3580 break; 3581 case WifiMonitor.NETWORK_CONNECTION_EVENT: 3582 event.type = StaEvent.TYPE_NETWORK_CONNECTION_EVENT; 3583 break; 3584 case WifiMonitor.NETWORK_DISCONNECTION_EVENT: 3585 event.type = StaEvent.TYPE_NETWORK_DISCONNECTION_EVENT; 3586 event.reason = msg.arg2; 3587 event.localGen = msg.arg1 == 0 ? false : true; 3588 break; 3589 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT: 3590 logEvent = false; 3591 StateChangeResult stateChangeResult = (StateChangeResult) msg.obj; 3592 mSupplicantStateChangeBitmask |= supplicantStateToBit(stateChangeResult.state); 3593 break; 3594 case ClientModeImpl.CMD_ASSOCIATED_BSSID: 3595 event.type = StaEvent.TYPE_CMD_ASSOCIATED_BSSID; 3596 break; 3597 case ClientModeImpl.CMD_TARGET_BSSID: 3598 event.type = StaEvent.TYPE_CMD_TARGET_BSSID; 3599 break; 3600 default: 3601 return; 3602 } 3603 if (logEvent) { 3604 addStaEvent(event); 3605 } 3606 } 3607 /** 3608 * Log a StaEvent from ClientModeImpl. The StaEvent must not be one of the supplicant 3609 * generated event types, which are logged through 'sendMessage' 3610 * @param type StaEvent.EventType describing the event 3611 */ logStaEvent(int type)3612 public void logStaEvent(int type) { 3613 logStaEvent(type, StaEvent.DISCONNECT_UNKNOWN, null); 3614 } 3615 /** 3616 * Log a StaEvent from ClientModeImpl. The StaEvent must not be one of the supplicant 3617 * generated event types, which are logged through 'sendMessage' 3618 * @param type StaEvent.EventType describing the event 3619 * @param config WifiConfiguration for a framework initiated connection attempt 3620 */ logStaEvent(int type, WifiConfiguration config)3621 public void logStaEvent(int type, WifiConfiguration config) { 3622 logStaEvent(type, StaEvent.DISCONNECT_UNKNOWN, config); 3623 } 3624 /** 3625 * Log a StaEvent from ClientModeImpl. The StaEvent must not be one of the supplicant 3626 * generated event types, which are logged through 'sendMessage' 3627 * @param type StaEvent.EventType describing the event 3628 * @param frameworkDisconnectReason StaEvent.FrameworkDisconnectReason explaining why framework 3629 * initiated a FRAMEWORK_DISCONNECT 3630 */ logStaEvent(int type, int frameworkDisconnectReason)3631 public void logStaEvent(int type, int frameworkDisconnectReason) { 3632 logStaEvent(type, frameworkDisconnectReason, null); 3633 } 3634 /** 3635 * Log a StaEvent from ClientModeImpl. The StaEvent must not be one of the supplicant 3636 * generated event types, which are logged through 'sendMessage' 3637 * @param type StaEvent.EventType describing the event 3638 * @param frameworkDisconnectReason StaEvent.FrameworkDisconnectReason explaining why framework 3639 * initiated a FRAMEWORK_DISCONNECT 3640 * @param config WifiConfiguration for a framework initiated connection attempt 3641 */ logStaEvent(int type, int frameworkDisconnectReason, WifiConfiguration config)3642 public void logStaEvent(int type, int frameworkDisconnectReason, WifiConfiguration config) { 3643 switch (type) { 3644 case StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL: 3645 case StaEvent.TYPE_CMD_IP_CONFIGURATION_LOST: 3646 case StaEvent.TYPE_CMD_IP_REACHABILITY_LOST: 3647 case StaEvent.TYPE_CMD_START_CONNECT: 3648 case StaEvent.TYPE_CMD_START_ROAM: 3649 case StaEvent.TYPE_CONNECT_NETWORK: 3650 case StaEvent.TYPE_NETWORK_AGENT_VALID_NETWORK: 3651 case StaEvent.TYPE_FRAMEWORK_DISCONNECT: 3652 case StaEvent.TYPE_SCORE_BREACH: 3653 case StaEvent.TYPE_MAC_CHANGE: 3654 case StaEvent.TYPE_WIFI_ENABLED: 3655 case StaEvent.TYPE_WIFI_DISABLED: 3656 case StaEvent.TYPE_WIFI_USABILITY_SCORE_BREACH: 3657 break; 3658 default: 3659 Log.e(TAG, "Unknown StaEvent:" + type); 3660 return; 3661 } 3662 StaEvent event = new StaEvent(); 3663 event.type = type; 3664 if (frameworkDisconnectReason != StaEvent.DISCONNECT_UNKNOWN) { 3665 event.frameworkDisconnectReason = frameworkDisconnectReason; 3666 } 3667 event.configInfo = createConfigInfo(config); 3668 addStaEvent(event); 3669 } 3670 addStaEvent(StaEvent staEvent)3671 private void addStaEvent(StaEvent staEvent) { 3672 staEvent.startTimeMillis = mClock.getElapsedSinceBootMillis(); 3673 staEvent.lastRssi = mLastPollRssi; 3674 staEvent.lastFreq = mLastPollFreq; 3675 staEvent.lastLinkSpeed = mLastPollLinkSpeed; 3676 staEvent.supplicantStateChangesBitmask = mSupplicantStateChangeBitmask; 3677 staEvent.lastScore = mLastScore; 3678 staEvent.lastWifiUsabilityScore = mLastWifiUsabilityScore; 3679 staEvent.lastPredictionHorizonSec = mLastPredictionHorizonSec; 3680 mSupplicantStateChangeBitmask = 0; 3681 mLastPollRssi = -127; 3682 mLastPollFreq = -1; 3683 mLastPollLinkSpeed = -1; 3684 mLastScore = -1; 3685 mLastWifiUsabilityScore = -1; 3686 mLastPredictionHorizonSec = -1; 3687 mStaEventList.add(new StaEventWithTime(staEvent, mClock.getWallClockMillis())); 3688 // Prune StaEventList if it gets too long 3689 if (mStaEventList.size() > MAX_STA_EVENTS) mStaEventList.remove(); 3690 } 3691 createConfigInfo(WifiConfiguration config)3692 private ConfigInfo createConfigInfo(WifiConfiguration config) { 3693 if (config == null) return null; 3694 ConfigInfo info = new ConfigInfo(); 3695 info.allowedKeyManagement = bitSetToInt(config.allowedKeyManagement); 3696 info.allowedProtocols = bitSetToInt(config.allowedProtocols); 3697 info.allowedAuthAlgorithms = bitSetToInt(config.allowedAuthAlgorithms); 3698 info.allowedPairwiseCiphers = bitSetToInt(config.allowedPairwiseCiphers); 3699 info.allowedGroupCiphers = bitSetToInt(config.allowedGroupCiphers); 3700 info.hiddenSsid = config.hiddenSSID; 3701 info.isPasspoint = config.isPasspoint(); 3702 info.isEphemeral = config.isEphemeral(); 3703 info.hasEverConnected = config.getNetworkSelectionStatus().getHasEverConnected(); 3704 ScanResult candidate = config.getNetworkSelectionStatus().getCandidate(); 3705 if (candidate != null) { 3706 info.scanRssi = candidate.level; 3707 info.scanFreq = candidate.frequency; 3708 } 3709 return info; 3710 } 3711 getHandler()3712 public Handler getHandler() { 3713 return mHandler; 3714 } 3715 getWifiAwareMetrics()3716 public WifiAwareMetrics getWifiAwareMetrics() { 3717 return mWifiAwareMetrics; 3718 } 3719 getWakeupMetrics()3720 public WifiWakeMetrics getWakeupMetrics() { 3721 return mWifiWakeMetrics; 3722 } 3723 getRttMetrics()3724 public RttMetrics getRttMetrics() { 3725 return mRttMetrics; 3726 } 3727 3728 // Rather than generate a StaEvent for each SUPPLICANT_STATE_CHANGE, cache these in a bitmask 3729 // and attach it to the next event which is generated. 3730 private int mSupplicantStateChangeBitmask = 0; 3731 3732 /** 3733 * Converts a SupplicantState value to a single bit, with position defined by 3734 * {@code StaEvent.SupplicantState} 3735 */ supplicantStateToBit(SupplicantState state)3736 public static int supplicantStateToBit(SupplicantState state) { 3737 switch(state) { 3738 case DISCONNECTED: 3739 return 1 << StaEvent.STATE_DISCONNECTED; 3740 case INTERFACE_DISABLED: 3741 return 1 << StaEvent.STATE_INTERFACE_DISABLED; 3742 case INACTIVE: 3743 return 1 << StaEvent.STATE_INACTIVE; 3744 case SCANNING: 3745 return 1 << StaEvent.STATE_SCANNING; 3746 case AUTHENTICATING: 3747 return 1 << StaEvent.STATE_AUTHENTICATING; 3748 case ASSOCIATING: 3749 return 1 << StaEvent.STATE_ASSOCIATING; 3750 case ASSOCIATED: 3751 return 1 << StaEvent.STATE_ASSOCIATED; 3752 case FOUR_WAY_HANDSHAKE: 3753 return 1 << StaEvent.STATE_FOUR_WAY_HANDSHAKE; 3754 case GROUP_HANDSHAKE: 3755 return 1 << StaEvent.STATE_GROUP_HANDSHAKE; 3756 case COMPLETED: 3757 return 1 << StaEvent.STATE_COMPLETED; 3758 case DORMANT: 3759 return 1 << StaEvent.STATE_DORMANT; 3760 case UNINITIALIZED: 3761 return 1 << StaEvent.STATE_UNINITIALIZED; 3762 case INVALID: 3763 return 1 << StaEvent.STATE_INVALID; 3764 default: 3765 Log.wtf(TAG, "Got unknown supplicant state: " + state.ordinal()); 3766 return 0; 3767 } 3768 } 3769 supplicantStateChangesBitmaskToString(int mask)3770 private static String supplicantStateChangesBitmaskToString(int mask) { 3771 StringBuilder sb = new StringBuilder(); 3772 sb.append("supplicantStateChangeEvents: {"); 3773 if ((mask & (1 << StaEvent.STATE_DISCONNECTED)) > 0) sb.append(" DISCONNECTED"); 3774 if ((mask & (1 << StaEvent.STATE_INTERFACE_DISABLED)) > 0) sb.append(" INTERFACE_DISABLED"); 3775 if ((mask & (1 << StaEvent.STATE_INACTIVE)) > 0) sb.append(" INACTIVE"); 3776 if ((mask & (1 << StaEvent.STATE_SCANNING)) > 0) sb.append(" SCANNING"); 3777 if ((mask & (1 << StaEvent.STATE_AUTHENTICATING)) > 0) sb.append(" AUTHENTICATING"); 3778 if ((mask & (1 << StaEvent.STATE_ASSOCIATING)) > 0) sb.append(" ASSOCIATING"); 3779 if ((mask & (1 << StaEvent.STATE_ASSOCIATED)) > 0) sb.append(" ASSOCIATED"); 3780 if ((mask & (1 << StaEvent.STATE_FOUR_WAY_HANDSHAKE)) > 0) sb.append(" FOUR_WAY_HANDSHAKE"); 3781 if ((mask & (1 << StaEvent.STATE_GROUP_HANDSHAKE)) > 0) sb.append(" GROUP_HANDSHAKE"); 3782 if ((mask & (1 << StaEvent.STATE_COMPLETED)) > 0) sb.append(" COMPLETED"); 3783 if ((mask & (1 << StaEvent.STATE_DORMANT)) > 0) sb.append(" DORMANT"); 3784 if ((mask & (1 << StaEvent.STATE_UNINITIALIZED)) > 0) sb.append(" UNINITIALIZED"); 3785 if ((mask & (1 << StaEvent.STATE_INVALID)) > 0) sb.append(" INVALID"); 3786 sb.append(" }"); 3787 return sb.toString(); 3788 } 3789 3790 /** 3791 * Returns a human readable string from a Sta Event. Only adds information relevant to the event 3792 * type. 3793 */ staEventToString(StaEvent event)3794 public static String staEventToString(StaEvent event) { 3795 if (event == null) return "<NULL>"; 3796 StringBuilder sb = new StringBuilder(); 3797 switch (event.type) { 3798 case StaEvent.TYPE_ASSOCIATION_REJECTION_EVENT: 3799 sb.append("ASSOCIATION_REJECTION_EVENT") 3800 .append(" timedOut=").append(event.associationTimedOut) 3801 .append(" status=").append(event.status).append(":") 3802 .append(ISupplicantStaIfaceCallback.StatusCode.toString(event.status)); 3803 break; 3804 case StaEvent.TYPE_AUTHENTICATION_FAILURE_EVENT: 3805 sb.append("AUTHENTICATION_FAILURE_EVENT reason=").append(event.authFailureReason) 3806 .append(":").append(authFailureReasonToString(event.authFailureReason)); 3807 break; 3808 case StaEvent.TYPE_NETWORK_CONNECTION_EVENT: 3809 sb.append("NETWORK_CONNECTION_EVENT"); 3810 break; 3811 case StaEvent.TYPE_NETWORK_DISCONNECTION_EVENT: 3812 sb.append("NETWORK_DISCONNECTION_EVENT") 3813 .append(" local_gen=").append(event.localGen) 3814 .append(" reason=").append(event.reason).append(":") 3815 .append(ISupplicantStaIfaceCallback.ReasonCode.toString( 3816 (event.reason >= 0 ? event.reason : -1 * event.reason))); 3817 break; 3818 case StaEvent.TYPE_CMD_ASSOCIATED_BSSID: 3819 sb.append("CMD_ASSOCIATED_BSSID"); 3820 break; 3821 case StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL: 3822 sb.append("CMD_IP_CONFIGURATION_SUCCESSFUL"); 3823 break; 3824 case StaEvent.TYPE_CMD_IP_CONFIGURATION_LOST: 3825 sb.append("CMD_IP_CONFIGURATION_LOST"); 3826 break; 3827 case StaEvent.TYPE_CMD_IP_REACHABILITY_LOST: 3828 sb.append("CMD_IP_REACHABILITY_LOST"); 3829 break; 3830 case StaEvent.TYPE_CMD_TARGET_BSSID: 3831 sb.append("CMD_TARGET_BSSID"); 3832 break; 3833 case StaEvent.TYPE_CMD_START_CONNECT: 3834 sb.append("CMD_START_CONNECT"); 3835 break; 3836 case StaEvent.TYPE_CMD_START_ROAM: 3837 sb.append("CMD_START_ROAM"); 3838 break; 3839 case StaEvent.TYPE_CONNECT_NETWORK: 3840 sb.append("CONNECT_NETWORK"); 3841 break; 3842 case StaEvent.TYPE_NETWORK_AGENT_VALID_NETWORK: 3843 sb.append("NETWORK_AGENT_VALID_NETWORK"); 3844 break; 3845 case StaEvent.TYPE_FRAMEWORK_DISCONNECT: 3846 sb.append("FRAMEWORK_DISCONNECT") 3847 .append(" reason=") 3848 .append(frameworkDisconnectReasonToString(event.frameworkDisconnectReason)); 3849 break; 3850 case StaEvent.TYPE_SCORE_BREACH: 3851 sb.append("SCORE_BREACH"); 3852 break; 3853 case StaEvent.TYPE_MAC_CHANGE: 3854 sb.append("MAC_CHANGE"); 3855 break; 3856 case StaEvent.TYPE_WIFI_ENABLED: 3857 sb.append("WIFI_ENABLED"); 3858 break; 3859 case StaEvent.TYPE_WIFI_DISABLED: 3860 sb.append("WIFI_DISABLED"); 3861 break; 3862 case StaEvent.TYPE_WIFI_USABILITY_SCORE_BREACH: 3863 sb.append("WIFI_USABILITY_SCORE_BREACH"); 3864 break; 3865 case StaEvent.TYPE_LINK_PROBE: 3866 sb.append("LINK_PROBE"); 3867 sb.append(" linkProbeWasSuccess=").append(event.linkProbeWasSuccess); 3868 if (event.linkProbeWasSuccess) { 3869 sb.append(" linkProbeSuccessElapsedTimeMs=") 3870 .append(event.linkProbeSuccessElapsedTimeMs); 3871 } else { 3872 sb.append(" linkProbeFailureReason=").append(event.linkProbeFailureReason); 3873 } 3874 break; 3875 default: 3876 sb.append("UNKNOWN " + event.type + ":"); 3877 break; 3878 } 3879 if (event.lastRssi != -127) sb.append(" lastRssi=").append(event.lastRssi); 3880 if (event.lastFreq != -1) sb.append(" lastFreq=").append(event.lastFreq); 3881 if (event.lastLinkSpeed != -1) sb.append(" lastLinkSpeed=").append(event.lastLinkSpeed); 3882 if (event.lastScore != -1) sb.append(" lastScore=").append(event.lastScore); 3883 if (event.lastWifiUsabilityScore != -1) { 3884 sb.append(" lastWifiUsabilityScore=").append(event.lastWifiUsabilityScore); 3885 sb.append(" lastPredictionHorizonSec=").append(event.lastPredictionHorizonSec); 3886 } 3887 if (event.supplicantStateChangesBitmask != 0) { 3888 sb.append(", ").append(supplicantStateChangesBitmaskToString( 3889 event.supplicantStateChangesBitmask)); 3890 } 3891 if (event.configInfo != null) { 3892 sb.append(", ").append(configInfoToString(event.configInfo)); 3893 } 3894 3895 return sb.toString(); 3896 } 3897 authFailureReasonToString(int authFailureReason)3898 private static String authFailureReasonToString(int authFailureReason) { 3899 switch (authFailureReason) { 3900 case StaEvent.AUTH_FAILURE_NONE: 3901 return "ERROR_AUTH_FAILURE_NONE"; 3902 case StaEvent.AUTH_FAILURE_TIMEOUT: 3903 return "ERROR_AUTH_FAILURE_TIMEOUT"; 3904 case StaEvent.AUTH_FAILURE_WRONG_PSWD: 3905 return "ERROR_AUTH_FAILURE_WRONG_PSWD"; 3906 case StaEvent.AUTH_FAILURE_EAP_FAILURE: 3907 return "ERROR_AUTH_FAILURE_EAP_FAILURE"; 3908 default: 3909 return ""; 3910 } 3911 } 3912 frameworkDisconnectReasonToString(int frameworkDisconnectReason)3913 private static String frameworkDisconnectReasonToString(int frameworkDisconnectReason) { 3914 switch (frameworkDisconnectReason) { 3915 case StaEvent.DISCONNECT_API: 3916 return "DISCONNECT_API"; 3917 case StaEvent.DISCONNECT_GENERIC: 3918 return "DISCONNECT_GENERIC"; 3919 case StaEvent.DISCONNECT_UNWANTED: 3920 return "DISCONNECT_UNWANTED"; 3921 case StaEvent.DISCONNECT_ROAM_WATCHDOG_TIMER: 3922 return "DISCONNECT_ROAM_WATCHDOG_TIMER"; 3923 case StaEvent.DISCONNECT_P2P_DISCONNECT_WIFI_REQUEST: 3924 return "DISCONNECT_P2P_DISCONNECT_WIFI_REQUEST"; 3925 case StaEvent.DISCONNECT_RESET_SIM_NETWORKS: 3926 return "DISCONNECT_RESET_SIM_NETWORKS"; 3927 default: 3928 return "DISCONNECT_UNKNOWN=" + frameworkDisconnectReason; 3929 } 3930 } 3931 configInfoToString(ConfigInfo info)3932 private static String configInfoToString(ConfigInfo info) { 3933 StringBuilder sb = new StringBuilder(); 3934 sb.append("ConfigInfo:") 3935 .append(" allowed_key_management=").append(info.allowedKeyManagement) 3936 .append(" allowed_protocols=").append(info.allowedProtocols) 3937 .append(" allowed_auth_algorithms=").append(info.allowedAuthAlgorithms) 3938 .append(" allowed_pairwise_ciphers=").append(info.allowedPairwiseCiphers) 3939 .append(" allowed_group_ciphers=").append(info.allowedGroupCiphers) 3940 .append(" hidden_ssid=").append(info.hiddenSsid) 3941 .append(" is_passpoint=").append(info.isPasspoint) 3942 .append(" is_ephemeral=").append(info.isEphemeral) 3943 .append(" has_ever_connected=").append(info.hasEverConnected) 3944 .append(" scan_rssi=").append(info.scanRssi) 3945 .append(" scan_freq=").append(info.scanFreq); 3946 return sb.toString(); 3947 } 3948 3949 /** 3950 * Converts the first 31 bits of a BitSet to a little endian int 3951 */ bitSetToInt(BitSet bits)3952 private static int bitSetToInt(BitSet bits) { 3953 int value = 0; 3954 int nBits = bits.length() < 31 ? bits.length() : 31; 3955 for (int i = 0; i < nBits; i++) { 3956 value += bits.get(i) ? (1 << i) : 0; 3957 } 3958 return value; 3959 } 3960 private void incrementSsid(SparseIntArray sia, int element) { 3961 increment(sia, Math.min(element, MAX_CONNECTABLE_SSID_NETWORK_BUCKET)); 3962 } 3963 private void incrementBssid(SparseIntArray sia, int element) { 3964 increment(sia, Math.min(element, MAX_CONNECTABLE_BSSID_NETWORK_BUCKET)); 3965 } 3966 private void incrementTotalScanResults(SparseIntArray sia, int element) { 3967 increment(sia, Math.min(element, MAX_TOTAL_SCAN_RESULTS_BUCKET)); 3968 } 3969 private void incrementTotalScanSsids(SparseIntArray sia, int element) { 3970 increment(sia, Math.min(element, MAX_TOTAL_SCAN_RESULT_SSIDS_BUCKET)); 3971 } 3972 private void incrementTotalPasspointAps(SparseIntArray sia, int element) { 3973 increment(sia, Math.min(element, MAX_TOTAL_PASSPOINT_APS_BUCKET)); 3974 } 3975 private void incrementTotalUniquePasspointEss(SparseIntArray sia, int element) { 3976 increment(sia, Math.min(element, MAX_TOTAL_PASSPOINT_UNIQUE_ESS_BUCKET)); 3977 } 3978 private void incrementPasspointPerUniqueEss(SparseIntArray sia, int element) { 3979 increment(sia, Math.min(element, MAX_PASSPOINT_APS_PER_UNIQUE_ESS_BUCKET)); 3980 } 3981 private void increment80211mcAps(SparseIntArray sia, int element) { 3982 increment(sia, Math.min(element, MAX_TOTAL_80211MC_APS_BUCKET)); 3983 } 3984 private void increment(SparseIntArray sia, int element) { 3985 int count = sia.get(element); 3986 sia.put(element, count + 1); 3987 } 3988 3989 private static class StaEventWithTime { 3990 public StaEvent staEvent; 3991 public long wallClockMillis; 3992 3993 StaEventWithTime(StaEvent event, long wallClockMillis) { 3994 staEvent = event; 3995 this.wallClockMillis = wallClockMillis; 3996 } 3997 3998 public String toString() { 3999 StringBuilder sb = new StringBuilder(); 4000 Calendar c = Calendar.getInstance(); 4001 c.setTimeInMillis(wallClockMillis); 4002 if (wallClockMillis != 0) { 4003 sb.append(String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)); 4004 } else { 4005 sb.append(" "); 4006 } 4007 sb.append(" ").append(staEventToString(staEvent)); 4008 return sb.toString(); 4009 } 4010 } 4011 4012 private LinkedList<WifiIsUnusableWithTime> mWifiIsUnusableList = 4013 new LinkedList<WifiIsUnusableWithTime>(); 4014 private long mTxScucessDelta = 0; 4015 private long mTxRetriesDelta = 0; 4016 private long mTxBadDelta = 0; 4017 private long mRxSuccessDelta = 0; 4018 private long mLlStatsUpdateTimeDelta = 0; 4019 private long mLlStatsLastUpdateTime = 0; 4020 private int mLastScoreNoReset = -1; 4021 private long mLastDataStallTime = Long.MIN_VALUE; 4022 4023 private static class WifiIsUnusableWithTime { 4024 public WifiIsUnusableEvent event; 4025 public long wallClockMillis; 4026 4027 WifiIsUnusableWithTime(WifiIsUnusableEvent event, long wallClockMillis) { 4028 this.event = event; 4029 this.wallClockMillis = wallClockMillis; 4030 } 4031 4032 public String toString() { 4033 if (event == null) return "<NULL>"; 4034 StringBuilder sb = new StringBuilder(); 4035 if (wallClockMillis != 0) { 4036 Calendar c = Calendar.getInstance(); 4037 c.setTimeInMillis(wallClockMillis); 4038 sb.append(String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)); 4039 } else { 4040 sb.append(" "); 4041 } 4042 sb.append(" "); 4043 4044 switch(event.type) { 4045 case WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX: 4046 sb.append("DATA_STALL_BAD_TX"); 4047 break; 4048 case WifiIsUnusableEvent.TYPE_DATA_STALL_TX_WITHOUT_RX: 4049 sb.append("DATA_STALL_TX_WITHOUT_RX"); 4050 break; 4051 case WifiIsUnusableEvent.TYPE_DATA_STALL_BOTH: 4052 sb.append("DATA_STALL_BOTH"); 4053 break; 4054 case WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT: 4055 sb.append("FIRMWARE_ALERT"); 4056 break; 4057 default: 4058 sb.append("UNKNOWN " + event.type); 4059 break; 4060 } 4061 4062 sb.append(" lastScore=").append(event.lastScore); 4063 sb.append(" txSuccessDelta=").append(event.txSuccessDelta); 4064 sb.append(" txRetriesDelta=").append(event.txRetriesDelta); 4065 sb.append(" txBadDelta=").append(event.txBadDelta); 4066 sb.append(" rxSuccessDelta=").append(event.rxSuccessDelta); 4067 sb.append(" packetUpdateTimeDelta=").append(event.packetUpdateTimeDelta) 4068 .append("ms"); 4069 if (event.firmwareAlertCode != -1) { 4070 sb.append(" firmwareAlertCode=").append(event.firmwareAlertCode); 4071 } 4072 sb.append(" lastWifiUsabilityScore=").append(event.lastWifiUsabilityScore); 4073 sb.append(" lastPredictionHorizonSec=").append(event.lastPredictionHorizonSec); 4074 return sb.toString(); 4075 } 4076 } 4077 4078 /** 4079 * Update the difference between the last two WifiLinkLayerStats for WifiIsUnusableEvent 4080 */ 4081 public void updateWifiIsUnusableLinkLayerStats(long txSuccessDelta, long txRetriesDelta, 4082 long txBadDelta, long rxSuccessDelta, long updateTimeDelta) { 4083 mTxScucessDelta = txSuccessDelta; 4084 mTxRetriesDelta = txRetriesDelta; 4085 mTxBadDelta = txBadDelta; 4086 mRxSuccessDelta = rxSuccessDelta; 4087 mLlStatsUpdateTimeDelta = updateTimeDelta; 4088 mLlStatsLastUpdateTime = mClock.getElapsedSinceBootMillis(); 4089 } 4090 4091 /** 4092 * Clear the saved difference between the last two WifiLinkLayerStats 4093 */ 4094 public void resetWifiIsUnusableLinkLayerStats() { 4095 mTxScucessDelta = 0; 4096 mTxRetriesDelta = 0; 4097 mTxBadDelta = 0; 4098 mRxSuccessDelta = 0; 4099 mLlStatsUpdateTimeDelta = 0; 4100 mLlStatsLastUpdateTime = 0; 4101 mLastDataStallTime = Long.MIN_VALUE; 4102 } 4103 4104 /** 4105 * Log a WifiIsUnusableEvent 4106 * @param triggerType WifiIsUnusableEvent.type describing the event 4107 */ 4108 public void logWifiIsUnusableEvent(int triggerType) { 4109 logWifiIsUnusableEvent(triggerType, -1); 4110 } 4111 4112 /** 4113 * Log a WifiIsUnusableEvent 4114 * @param triggerType WifiIsUnusableEvent.type describing the event 4115 * @param firmwareAlertCode WifiIsUnusableEvent.firmwareAlertCode for firmware alert code 4116 */ 4117 public void logWifiIsUnusableEvent(int triggerType, int firmwareAlertCode) { 4118 mScoreBreachLowTimeMillis = -1; 4119 if (!mUnusableEventLogging) { 4120 return; 4121 } 4122 4123 long currentBootTime = mClock.getElapsedSinceBootMillis(); 4124 switch (triggerType) { 4125 case WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX: 4126 case WifiIsUnusableEvent.TYPE_DATA_STALL_TX_WITHOUT_RX: 4127 case WifiIsUnusableEvent.TYPE_DATA_STALL_BOTH: 4128 // Have a time-based throttle for generating WifiIsUnusableEvent from data stalls 4129 if (currentBootTime < mLastDataStallTime + MIN_DATA_STALL_WAIT_MS) { 4130 return; 4131 } 4132 mLastDataStallTime = currentBootTime; 4133 break; 4134 case WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT: 4135 break; 4136 case WifiIsUnusableEvent.TYPE_IP_REACHABILITY_LOST: 4137 break; 4138 default: 4139 Log.e(TAG, "Unknown WifiIsUnusableEvent: " + triggerType); 4140 return; 4141 } 4142 4143 WifiIsUnusableEvent event = new WifiIsUnusableEvent(); 4144 event.type = triggerType; 4145 if (triggerType == WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT) { 4146 event.firmwareAlertCode = firmwareAlertCode; 4147 } 4148 event.startTimeMillis = currentBootTime; 4149 event.lastScore = mLastScoreNoReset; 4150 event.lastWifiUsabilityScore = mLastWifiUsabilityScoreNoReset; 4151 event.lastPredictionHorizonSec = mLastPredictionHorizonSecNoReset; 4152 event.txSuccessDelta = mTxScucessDelta; 4153 event.txRetriesDelta = mTxRetriesDelta; 4154 event.txBadDelta = mTxBadDelta; 4155 event.rxSuccessDelta = mRxSuccessDelta; 4156 event.packetUpdateTimeDelta = mLlStatsUpdateTimeDelta; 4157 event.lastLinkLayerStatsUpdateTime = mLlStatsLastUpdateTime; 4158 event.screenOn = mScreenOn; 4159 4160 mWifiIsUnusableList.add(new WifiIsUnusableWithTime(event, mClock.getWallClockMillis())); 4161 if (mWifiIsUnusableList.size() > MAX_UNUSABLE_EVENTS) { 4162 mWifiIsUnusableList.removeFirst(); 4163 } 4164 } 4165 4166 /** 4167 * Sets whether or not WifiIsUnusableEvent is logged in metrics 4168 */ 4169 @VisibleForTesting 4170 public void setWifiIsUnusableLoggingEnabled(boolean enabled) { 4171 synchronized (mLock) { 4172 mExperimentValues.wifiIsUnusableLoggingEnabled = enabled; 4173 } 4174 } 4175 4176 /** 4177 * Sets whether or not LinkSpeedCounts is logged in metrics 4178 */ 4179 @VisibleForTesting 4180 public void setLinkSpeedCountsLoggingEnabled(boolean enabled) { 4181 synchronized (mLock) { 4182 mExperimentValues.linkSpeedCountsLoggingEnabled = enabled; 4183 } 4184 } 4185 4186 /** 4187 * Sets the minimum number of txBad to trigger a data stall 4188 */ 4189 public void setWifiDataStallMinTxBad(int minTxBad) { 4190 synchronized (mLock) { 4191 mExperimentValues.wifiDataStallMinTxBad = minTxBad; 4192 } 4193 } 4194 4195 /** 4196 * Sets the minimum number of txSuccess to trigger a data stall 4197 * when rxSuccess is 0 4198 */ 4199 public void setWifiDataStallMinRxWithoutTx(int minTxSuccessWithoutRx) { 4200 synchronized (mLock) { 4201 mExperimentValues.wifiDataStallMinTxSuccessWithoutRx = minTxSuccessWithoutRx; 4202 } 4203 } 4204 4205 /** 4206 * Extract data from |info| and |stats| to build a WifiUsabilityStatsEntry and then adds it 4207 * into an internal ring buffer. 4208 * @param info 4209 * @param stats 4210 */ 4211 public void updateWifiUsabilityStatsEntries(WifiInfo info, WifiLinkLayerStats stats) { 4212 synchronized (mLock) { 4213 if (info == null || stats == null) { 4214 return; 4215 } 4216 WifiUsabilityStatsEntry wifiUsabilityStatsEntry = 4217 mWifiUsabilityStatsEntriesList.size() 4218 < MAX_WIFI_USABILITY_STATS_ENTRIES_LIST_SIZE 4219 ? new WifiUsabilityStatsEntry() : mWifiUsabilityStatsEntriesList.remove(); 4220 wifiUsabilityStatsEntry.timeStampMs = stats.timeStampInMs; 4221 wifiUsabilityStatsEntry.totalTxSuccess = stats.txmpdu_be + stats.txmpdu_bk 4222 + stats.txmpdu_vi + stats.txmpdu_vo; 4223 wifiUsabilityStatsEntry.totalTxRetries = stats.retries_be + stats.retries_bk 4224 + stats.retries_vi + stats.retries_vo; 4225 wifiUsabilityStatsEntry.totalTxBad = stats.lostmpdu_be + stats.lostmpdu_bk 4226 + stats.lostmpdu_vi + stats.lostmpdu_vo; 4227 wifiUsabilityStatsEntry.totalRxSuccess = stats.rxmpdu_be + stats.rxmpdu_bk 4228 + stats.rxmpdu_vi + stats.rxmpdu_vo; 4229 wifiUsabilityStatsEntry.totalRadioOnTimeMs = stats.on_time; 4230 wifiUsabilityStatsEntry.totalRadioTxTimeMs = stats.tx_time; 4231 wifiUsabilityStatsEntry.totalRadioRxTimeMs = stats.rx_time; 4232 wifiUsabilityStatsEntry.totalScanTimeMs = stats.on_time_scan; 4233 wifiUsabilityStatsEntry.totalNanScanTimeMs = stats.on_time_nan_scan; 4234 wifiUsabilityStatsEntry.totalBackgroundScanTimeMs = stats.on_time_background_scan; 4235 wifiUsabilityStatsEntry.totalRoamScanTimeMs = stats.on_time_roam_scan; 4236 wifiUsabilityStatsEntry.totalPnoScanTimeMs = stats.on_time_pno_scan; 4237 wifiUsabilityStatsEntry.totalHotspot2ScanTimeMs = stats.on_time_hs20_scan; 4238 wifiUsabilityStatsEntry.rssi = info.getRssi(); 4239 wifiUsabilityStatsEntry.linkSpeedMbps = info.getLinkSpeed(); 4240 WifiLinkLayerStats.ChannelStats statsMap = 4241 stats.channelStatsMap.get(info.getFrequency()); 4242 if (statsMap != null) { 4243 wifiUsabilityStatsEntry.totalRadioOnFreqTimeMs = statsMap.radioOnTimeMs; 4244 wifiUsabilityStatsEntry.totalCcaBusyFreqTimeMs = statsMap.ccaBusyTimeMs; 4245 } 4246 wifiUsabilityStatsEntry.totalBeaconRx = stats.beacon_rx; 4247 4248 boolean isSameBssidAndFreq = mLastBssid == null || mLastFrequency == -1 4249 || (mLastBssid.equals(info.getBSSID()) 4250 && mLastFrequency == info.getFrequency()); 4251 mLastBssid = info.getBSSID(); 4252 mLastFrequency = info.getFrequency(); 4253 wifiUsabilityStatsEntry.wifiScore = mLastScoreNoReset; 4254 wifiUsabilityStatsEntry.wifiUsabilityScore = mLastWifiUsabilityScoreNoReset; 4255 wifiUsabilityStatsEntry.seqNumToFramework = mSeqNumToFramework; 4256 wifiUsabilityStatsEntry.predictionHorizonSec = mLastPredictionHorizonSecNoReset; 4257 switch (mProbeStatusSinceLastUpdate) { 4258 case android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE: 4259 wifiUsabilityStatsEntry.probeStatusSinceLastUpdate = 4260 WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE; 4261 break; 4262 case android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS: 4263 wifiUsabilityStatsEntry.probeStatusSinceLastUpdate = 4264 WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS; 4265 break; 4266 case android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE: 4267 wifiUsabilityStatsEntry.probeStatusSinceLastUpdate = 4268 WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE; 4269 break; 4270 default: 4271 wifiUsabilityStatsEntry.probeStatusSinceLastUpdate = 4272 WifiUsabilityStatsEntry.PROBE_STATUS_UNKNOWN; 4273 Log.e(TAG, "Unknown link probe status: " + mProbeStatusSinceLastUpdate); 4274 } 4275 wifiUsabilityStatsEntry.probeElapsedTimeSinceLastUpdateMs = 4276 mProbeElapsedTimeSinceLastUpdateMs; 4277 wifiUsabilityStatsEntry.probeMcsRateSinceLastUpdate = mProbeMcsRateSinceLastUpdate; 4278 wifiUsabilityStatsEntry.rxLinkSpeedMbps = info.getRxLinkSpeedMbps(); 4279 wifiUsabilityStatsEntry.isSameBssidAndFreq = isSameBssidAndFreq; 4280 wifiUsabilityStatsEntry.seqNumInsideFramework = mSeqNumInsideFramework; 4281 wifiUsabilityStatsEntry.deviceMobilityState = mCurrentDeviceMobilityState; 4282 4283 CellularLinkLayerStats cls = mCellularLinkLayerStatsCollector.update(); 4284 if (DBG) Log.v(TAG, "Latest Cellular Link Layer Stats: " + cls); 4285 wifiUsabilityStatsEntry.cellularDataNetworkType = 4286 parseDataNetworkTypeToProto(cls.getDataNetworkType()); 4287 wifiUsabilityStatsEntry.cellularSignalStrengthDbm = cls.getSignalStrengthDbm(); 4288 wifiUsabilityStatsEntry.cellularSignalStrengthDb = cls.getSignalStrengthDb(); 4289 wifiUsabilityStatsEntry.isSameRegisteredCell = cls.getIsSameRegisteredCell(); 4290 4291 mWifiUsabilityStatsEntriesList.add(wifiUsabilityStatsEntry); 4292 mWifiUsabilityStatsCounter++; 4293 if (mWifiUsabilityStatsCounter >= NUM_WIFI_USABILITY_STATS_ENTRIES_PER_WIFI_GOOD) { 4294 addToWifiUsabilityStatsList(WifiUsabilityStats.LABEL_GOOD, 4295 WifiUsabilityStats.TYPE_UNKNOWN, -1); 4296 } 4297 if (mScoreBreachLowTimeMillis != -1) { 4298 long elapsedTime = mClock.getElapsedSinceBootMillis() - mScoreBreachLowTimeMillis; 4299 if (elapsedTime >= MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS) { 4300 mScoreBreachLowTimeMillis = -1; 4301 if (elapsedTime <= VALIDITY_PERIOD_OF_SCORE_BREACH_LOW_MS) { 4302 addToWifiUsabilityStatsList(WifiUsabilityStats.LABEL_GOOD, 4303 WifiUsabilityStats.TYPE_UNKNOWN, -1); 4304 } 4305 } 4306 } 4307 4308 // Invoke Wifi usability stats listener. 4309 sendWifiUsabilityStats(mSeqNumInsideFramework, isSameBssidAndFreq, 4310 createNewWifiUsabilityStatsEntryParcelable(wifiUsabilityStatsEntry)); 4311 4312 mSeqNumInsideFramework++; 4313 mProbeStatusSinceLastUpdate = 4314 android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE; 4315 mProbeElapsedTimeSinceLastUpdateMs = -1; 4316 mProbeMcsRateSinceLastUpdate = -1; 4317 } 4318 } 4319 4320 private int parseDataNetworkTypeToProto(int cellularDataNetworkType) { 4321 switch (cellularDataNetworkType) { 4322 case TelephonyManager.NETWORK_TYPE_UNKNOWN: 4323 return WifiUsabilityStatsEntry.NETWORK_TYPE_UNKNOWN; 4324 case TelephonyManager.NETWORK_TYPE_GSM: 4325 return WifiUsabilityStatsEntry.NETWORK_TYPE_GSM; 4326 case TelephonyManager.NETWORK_TYPE_CDMA: 4327 return WifiUsabilityStatsEntry.NETWORK_TYPE_CDMA; 4328 case TelephonyManager.NETWORK_TYPE_EVDO_0: 4329 return WifiUsabilityStatsEntry.NETWORK_TYPE_EVDO_0; 4330 case TelephonyManager.NETWORK_TYPE_UMTS: 4331 return WifiUsabilityStatsEntry.NETWORK_TYPE_UMTS; 4332 case TelephonyManager.NETWORK_TYPE_TD_SCDMA: 4333 return WifiUsabilityStatsEntry.NETWORK_TYPE_TD_SCDMA; 4334 case TelephonyManager.NETWORK_TYPE_LTE: 4335 return WifiUsabilityStatsEntry.NETWORK_TYPE_LTE; 4336 case TelephonyManager.NETWORK_TYPE_NR: 4337 return WifiUsabilityStatsEntry.NETWORK_TYPE_NR; 4338 default: 4339 Log.e(TAG, "Unknown data network type : " + cellularDataNetworkType); 4340 return WifiUsabilityStatsEntry.NETWORK_TYPE_UNKNOWN; 4341 } 4342 } 4343 4344 private int parseDataNetworkTypeFromProto(int cellularDataNetworkType) { 4345 switch (cellularDataNetworkType) { 4346 case WifiUsabilityStatsEntry.NETWORK_TYPE_UNKNOWN: 4347 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 4348 case WifiUsabilityStatsEntry.NETWORK_TYPE_GSM: 4349 return TelephonyManager.NETWORK_TYPE_GSM; 4350 case WifiUsabilityStatsEntry.NETWORK_TYPE_CDMA: 4351 return TelephonyManager.NETWORK_TYPE_CDMA; 4352 case WifiUsabilityStatsEntry.NETWORK_TYPE_EVDO_0: 4353 return TelephonyManager.NETWORK_TYPE_EVDO_0; 4354 case WifiUsabilityStatsEntry.NETWORK_TYPE_UMTS: 4355 return TelephonyManager.NETWORK_TYPE_UMTS; 4356 case WifiUsabilityStatsEntry.NETWORK_TYPE_TD_SCDMA: 4357 return TelephonyManager.NETWORK_TYPE_TD_SCDMA; 4358 case WifiUsabilityStatsEntry.NETWORK_TYPE_LTE: 4359 return TelephonyManager.NETWORK_TYPE_LTE; 4360 case WifiUsabilityStatsEntry.NETWORK_TYPE_NR: 4361 return TelephonyManager.NETWORK_TYPE_NR; 4362 default: 4363 Log.e(TAG, "Unknown data network type : " + cellularDataNetworkType); 4364 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 4365 } 4366 } 4367 /** 4368 * Send Wifi usability stats. 4369 * @param seqNum 4370 * @param isSameBssidAndFreq 4371 * @param statsEntry 4372 */ 4373 private void sendWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq, 4374 android.net.wifi.WifiUsabilityStatsEntry statsEntry) { 4375 for (IOnWifiUsabilityStatsListener listener : mOnWifiUsabilityListeners.getCallbacks()) { 4376 try { 4377 listener.onWifiUsabilityStats(seqNum, isSameBssidAndFreq, statsEntry); 4378 } catch (RemoteException e) { 4379 Log.e(TAG, "Unable to invoke Wifi usability stats entry listener " 4380 + listener, e); 4381 } 4382 } 4383 } 4384 4385 private android.net.wifi.WifiUsabilityStatsEntry createNewWifiUsabilityStatsEntryParcelable( 4386 WifiUsabilityStatsEntry s) { 4387 int probeStatus; 4388 switch (s.probeStatusSinceLastUpdate) { 4389 case WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE: 4390 probeStatus = android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE; 4391 break; 4392 case WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS: 4393 probeStatus = android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS; 4394 break; 4395 case WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE: 4396 probeStatus = android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE; 4397 break; 4398 default: 4399 probeStatus = android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_UNKNOWN; 4400 Log.e(TAG, "Unknown link probe status: " + s.probeStatusSinceLastUpdate); 4401 } 4402 int cellularDataNetworkType = parseDataNetworkTypeFromProto(s.cellularDataNetworkType); 4403 return new android.net.wifi.WifiUsabilityStatsEntry(s.timeStampMs, s.rssi, 4404 s.linkSpeedMbps, s.totalTxSuccess, s.totalTxRetries, 4405 s.totalTxBad, s.totalRxSuccess, s.totalRadioOnTimeMs, 4406 s.totalRadioTxTimeMs, s.totalRadioRxTimeMs, s.totalScanTimeMs, 4407 s.totalNanScanTimeMs, s.totalBackgroundScanTimeMs, s.totalRoamScanTimeMs, 4408 s.totalPnoScanTimeMs, s.totalHotspot2ScanTimeMs, s.totalCcaBusyFreqTimeMs, 4409 s.totalRadioOnFreqTimeMs, s.totalBeaconRx, probeStatus, 4410 s.probeElapsedTimeSinceLastUpdateMs, s.probeMcsRateSinceLastUpdate, 4411 s.rxLinkSpeedMbps, cellularDataNetworkType, 4412 s.cellularSignalStrengthDbm, s.cellularSignalStrengthDb, 4413 s.isSameRegisteredCell 4414 ); 4415 } 4416 4417 private WifiUsabilityStatsEntry createNewWifiUsabilityStatsEntry(WifiUsabilityStatsEntry s) { 4418 WifiUsabilityStatsEntry out = new WifiUsabilityStatsEntry(); 4419 out.timeStampMs = s.timeStampMs; 4420 out.totalTxSuccess = s.totalTxSuccess; 4421 out.totalTxRetries = s.totalTxRetries; 4422 out.totalTxBad = s.totalTxBad; 4423 out.totalRxSuccess = s.totalRxSuccess; 4424 out.totalRadioOnTimeMs = s.totalRadioOnTimeMs; 4425 out.totalRadioTxTimeMs = s.totalRadioTxTimeMs; 4426 out.totalRadioRxTimeMs = s.totalRadioRxTimeMs; 4427 out.totalScanTimeMs = s.totalScanTimeMs; 4428 out.totalNanScanTimeMs = s.totalNanScanTimeMs; 4429 out.totalBackgroundScanTimeMs = s.totalBackgroundScanTimeMs; 4430 out.totalRoamScanTimeMs = s.totalRoamScanTimeMs; 4431 out.totalPnoScanTimeMs = s.totalPnoScanTimeMs; 4432 out.totalHotspot2ScanTimeMs = s.totalHotspot2ScanTimeMs; 4433 out.rssi = s.rssi; 4434 out.linkSpeedMbps = s.linkSpeedMbps; 4435 out.totalCcaBusyFreqTimeMs = s.totalCcaBusyFreqTimeMs; 4436 out.totalRadioOnFreqTimeMs = s.totalRadioOnFreqTimeMs; 4437 out.totalBeaconRx = s.totalBeaconRx; 4438 out.wifiScore = s.wifiScore; 4439 out.wifiUsabilityScore = s.wifiUsabilityScore; 4440 out.seqNumToFramework = s.seqNumToFramework; 4441 out.predictionHorizonSec = s.predictionHorizonSec; 4442 out.probeStatusSinceLastUpdate = s.probeStatusSinceLastUpdate; 4443 out.probeElapsedTimeSinceLastUpdateMs = s.probeElapsedTimeSinceLastUpdateMs; 4444 out.probeMcsRateSinceLastUpdate = s.probeMcsRateSinceLastUpdate; 4445 out.rxLinkSpeedMbps = s.rxLinkSpeedMbps; 4446 out.isSameBssidAndFreq = s.isSameBssidAndFreq; 4447 out.seqNumInsideFramework = s.seqNumInsideFramework; 4448 out.cellularDataNetworkType = s.cellularDataNetworkType; 4449 out.cellularSignalStrengthDbm = s.cellularSignalStrengthDbm; 4450 out.cellularSignalStrengthDb = s.cellularSignalStrengthDb; 4451 out.isSameRegisteredCell = s.isSameRegisteredCell; 4452 out.deviceMobilityState = s.deviceMobilityState; 4453 return out; 4454 } 4455 4456 private WifiUsabilityStats createWifiUsabilityStatsWithLabel(int label, int triggerType, 4457 int firmwareAlertCode) { 4458 WifiUsabilityStats wifiUsabilityStats = new WifiUsabilityStats(); 4459 wifiUsabilityStats.label = label; 4460 wifiUsabilityStats.triggerType = triggerType; 4461 wifiUsabilityStats.firmwareAlertCode = firmwareAlertCode; 4462 wifiUsabilityStats.timeStampMs = mClock.getElapsedSinceBootMillis(); 4463 wifiUsabilityStats.stats = 4464 new WifiUsabilityStatsEntry[mWifiUsabilityStatsEntriesList.size()]; 4465 for (int i = 0; i < mWifiUsabilityStatsEntriesList.size(); i++) { 4466 wifiUsabilityStats.stats[i] = 4467 createNewWifiUsabilityStatsEntry(mWifiUsabilityStatsEntriesList.get(i)); 4468 } 4469 return wifiUsabilityStats; 4470 } 4471 4472 /** 4473 * Label the current snapshot of WifiUsabilityStatsEntrys and save the labeled data in memory. 4474 * @param label WifiUsabilityStats.LABEL_GOOD or WifiUsabilityStats.LABEL_BAD 4475 * @param triggerType what event triggers WifiUsabilityStats 4476 * @param firmwareAlertCode the firmware alert code when the stats was triggered by a 4477 * firmware alert 4478 */ 4479 public void addToWifiUsabilityStatsList(int label, int triggerType, int firmwareAlertCode) { 4480 synchronized (mLock) { 4481 if (mWifiUsabilityStatsEntriesList.isEmpty() || !mScreenOn) { 4482 return; 4483 } 4484 if (label == WifiUsabilityStats.LABEL_GOOD) { 4485 // Only add a good event if at least |MIN_WIFI_GOOD_USABILITY_STATS_PERIOD_MS| 4486 // has passed. 4487 if (mWifiUsabilityStatsListGood.isEmpty() 4488 || mWifiUsabilityStatsListGood.getLast().stats[mWifiUsabilityStatsListGood 4489 .getLast().stats.length - 1].timeStampMs 4490 + MIN_WIFI_GOOD_USABILITY_STATS_PERIOD_MS 4491 < mWifiUsabilityStatsEntriesList.getLast().timeStampMs) { 4492 while (mWifiUsabilityStatsListGood.size() 4493 >= MAX_WIFI_USABILITY_STATS_LIST_SIZE_PER_TYPE) { 4494 mWifiUsabilityStatsListGood.remove( 4495 mRand.nextInt(mWifiUsabilityStatsListGood.size())); 4496 } 4497 mWifiUsabilityStatsListGood.add( 4498 createWifiUsabilityStatsWithLabel(label, triggerType, 4499 firmwareAlertCode)); 4500 } 4501 } else { 4502 // Only add a bad event if at least |MIN_DATA_STALL_WAIT_MS| 4503 // has passed. 4504 mScoreBreachLowTimeMillis = -1; 4505 if (mWifiUsabilityStatsListBad.isEmpty() 4506 || (mWifiUsabilityStatsListBad.getLast().stats[mWifiUsabilityStatsListBad 4507 .getLast().stats.length - 1].timeStampMs 4508 + MIN_DATA_STALL_WAIT_MS 4509 < mWifiUsabilityStatsEntriesList.getLast().timeStampMs)) { 4510 while (mWifiUsabilityStatsListBad.size() 4511 >= MAX_WIFI_USABILITY_STATS_LIST_SIZE_PER_TYPE) { 4512 mWifiUsabilityStatsListBad.remove( 4513 mRand.nextInt(mWifiUsabilityStatsListBad.size())); 4514 } 4515 mWifiUsabilityStatsListBad.add( 4516 createWifiUsabilityStatsWithLabel(label, triggerType, 4517 firmwareAlertCode)); 4518 } 4519 } 4520 mWifiUsabilityStatsCounter = 0; 4521 } 4522 } 4523 4524 private DeviceMobilityStatePnoScanStats getOrCreateDeviceMobilityStatePnoScanStats( 4525 @DeviceMobilityState int deviceMobilityState) { 4526 DeviceMobilityStatePnoScanStats stats = mMobilityStatePnoStatsMap.get(deviceMobilityState); 4527 if (stats == null) { 4528 stats = new DeviceMobilityStatePnoScanStats(); 4529 stats.deviceMobilityState = deviceMobilityState; 4530 stats.numTimesEnteredState = 0; 4531 stats.totalDurationMs = 0; 4532 stats.pnoDurationMs = 0; 4533 mMobilityStatePnoStatsMap.put(deviceMobilityState, stats); 4534 } 4535 return stats; 4536 } 4537 4538 /** 4539 * Updates the current device mobility state's total duration. This method should be called 4540 * before entering a new device mobility state. 4541 */ 4542 private void updateCurrentMobilityStateTotalDuration(long now) { 4543 DeviceMobilityStatePnoScanStats stats = 4544 getOrCreateDeviceMobilityStatePnoScanStats(mCurrentDeviceMobilityState); 4545 stats.totalDurationMs += now - mCurrentDeviceMobilityStateStartMs; 4546 mCurrentDeviceMobilityStateStartMs = now; 4547 } 4548 4549 /** 4550 * Convert the IntCounter of passpoint profile types and counts to proto's 4551 * repeated IntKeyVal array. 4552 * 4553 * @param passpointProfileTypes passpoint profile types and counts. 4554 */ 4555 private PasspointProfileTypeCount[] convertPasspointProfilesToProto( 4556 IntCounter passpointProfileTypes) { 4557 return passpointProfileTypes.toProto(PasspointProfileTypeCount.class, (key, count) -> { 4558 PasspointProfileTypeCount entry = new PasspointProfileTypeCount(); 4559 entry.eapMethodType = key; 4560 entry.count = count; 4561 return entry; 4562 }); 4563 } 4564 4565 /** 4566 * Reports that the device entered a new mobility state. 4567 * 4568 * @param newState the new device mobility state. 4569 */ 4570 public void enterDeviceMobilityState(@DeviceMobilityState int newState) { 4571 synchronized (mLock) { 4572 long now = mClock.getElapsedSinceBootMillis(); 4573 updateCurrentMobilityStateTotalDuration(now); 4574 4575 if (newState == mCurrentDeviceMobilityState) return; 4576 4577 mCurrentDeviceMobilityState = newState; 4578 DeviceMobilityStatePnoScanStats stats = 4579 getOrCreateDeviceMobilityStatePnoScanStats(mCurrentDeviceMobilityState); 4580 stats.numTimesEnteredState++; 4581 } 4582 } 4583 4584 /** 4585 * Logs the start of a PNO scan. 4586 */ 4587 public void logPnoScanStart() { 4588 synchronized (mLock) { 4589 long now = mClock.getElapsedSinceBootMillis(); 4590 mCurrentDeviceMobilityStatePnoScanStartMs = now; 4591 updateCurrentMobilityStateTotalDuration(now); 4592 } 4593 } 4594 4595 /** 4596 * Logs the end of a PNO scan. This is attributed to the current device mobility state, as 4597 * logged by {@link #enterDeviceMobilityState(int)}. Thus, if the mobility state changes during 4598 * a PNO scan, one should call {@link #logPnoScanStop()}, {@link #enterDeviceMobilityState(int)} 4599 * , then {@link #logPnoScanStart()} so that the portion of PNO scan before the mobility state 4600 * change can be correctly attributed to the previous mobility state. 4601 */ 4602 public void logPnoScanStop() { 4603 synchronized (mLock) { 4604 if (mCurrentDeviceMobilityStatePnoScanStartMs < 0) { 4605 Log.e(TAG, "Called WifiMetrics#logPNoScanStop() without calling " 4606 + "WifiMetrics#logPnoScanStart() first!"); 4607 return; 4608 } 4609 DeviceMobilityStatePnoScanStats stats = 4610 getOrCreateDeviceMobilityStatePnoScanStats(mCurrentDeviceMobilityState); 4611 long now = mClock.getElapsedSinceBootMillis(); 4612 stats.pnoDurationMs += now - mCurrentDeviceMobilityStatePnoScanStartMs; 4613 mCurrentDeviceMobilityStatePnoScanStartMs = -1; 4614 updateCurrentMobilityStateTotalDuration(now); 4615 } 4616 } 4617 4618 /** 4619 * Add a new listener for Wi-Fi usability stats handling. 4620 */ 4621 public void addOnWifiUsabilityListener(IBinder binder, IOnWifiUsabilityStatsListener listener, 4622 int listenerIdentifier) { 4623 if (!mOnWifiUsabilityListeners.add(binder, listener, listenerIdentifier)) { 4624 Log.e(TAG, "Failed to add listener"); 4625 return; 4626 } 4627 if (DBG) { 4628 Log.v(TAG, "Adding listener. Num listeners: " 4629 + mOnWifiUsabilityListeners.getNumCallbacks()); 4630 } 4631 } 4632 4633 /** 4634 * Remove an existing listener for Wi-Fi usability stats handling. 4635 */ 4636 public void removeOnWifiUsabilityListener(int listenerIdentifier) { 4637 mOnWifiUsabilityListeners.remove(listenerIdentifier); 4638 if (DBG) { 4639 Log.v(TAG, "Removing listener. Num listeners: " 4640 + mOnWifiUsabilityListeners.getNumCallbacks()); 4641 } 4642 } 4643 4644 /** 4645 * Updates the Wi-Fi usability score and increments occurence of a particular Wifi usability 4646 * score passed in from outside framework. Scores are bounded within 4647 * [MIN_WIFI_USABILITY_SCORE, MAX_WIFI_USABILITY_SCORE]. 4648 * 4649 * Also records events when the Wifi usability score breaches significant thresholds. 4650 * 4651 * @param seqNum Sequence number of the Wi-Fi usability score. 4652 * @param score The Wi-Fi usability score. 4653 * @param predictionHorizonSec Prediction horizon of the Wi-Fi usability score. 4654 */ 4655 public void incrementWifiUsabilityScoreCount(int seqNum, int score, int predictionHorizonSec) { 4656 if (score < MIN_WIFI_USABILITY_SCORE || score > MAX_WIFI_USABILITY_SCORE) { 4657 return; 4658 } 4659 synchronized (mLock) { 4660 mSeqNumToFramework = seqNum; 4661 mLastWifiUsabilityScore = score; 4662 mLastWifiUsabilityScoreNoReset = score; 4663 mWifiUsabilityScoreCounts.put(score, mWifiUsabilityScoreCounts.get(score) + 1); 4664 mLastPredictionHorizonSec = predictionHorizonSec; 4665 mLastPredictionHorizonSecNoReset = predictionHorizonSec; 4666 4667 boolean wifiWins = mWifiWinsUsabilityScore; 4668 if (score > LOW_WIFI_USABILITY_SCORE) { 4669 wifiWins = true; 4670 } else if (score < LOW_WIFI_USABILITY_SCORE) { 4671 wifiWins = false; 4672 } 4673 4674 if (wifiWins != mWifiWinsUsabilityScore) { 4675 mWifiWinsUsabilityScore = wifiWins; 4676 StaEvent event = new StaEvent(); 4677 event.type = StaEvent.TYPE_WIFI_USABILITY_SCORE_BREACH; 4678 addStaEvent(event); 4679 // Only record the first score breach by checking whether mScoreBreachLowTimeMillis 4680 // has been set to -1 4681 if (!wifiWins && mScoreBreachLowTimeMillis == -1) { 4682 mScoreBreachLowTimeMillis = mClock.getElapsedSinceBootMillis(); 4683 } 4684 } 4685 } 4686 } 4687 4688 /** 4689 * Reports stats for a successful link probe. 4690 * 4691 * @param timeSinceLastTxSuccessMs At {@code startTimestampMs}, the number of milliseconds since 4692 * the last Tx success (according to 4693 * {@link WifiInfo#txSuccess}). 4694 * @param rssi The Rx RSSI at {@code startTimestampMs}. 4695 * @param linkSpeed The Tx link speed in Mbps at {@code startTimestampMs}. 4696 * @param elapsedTimeMs The number of milliseconds between when the command to transmit the 4697 * probe was sent to the driver and when the driver responded that the 4698 * probe was ACKed. Note: this number should be correlated with the number 4699 * of retries that the driver attempted before the probe was ACKed. 4700 */ 4701 public void logLinkProbeSuccess(long timeSinceLastTxSuccessMs, 4702 int rssi, int linkSpeed, int elapsedTimeMs) { 4703 synchronized (mLock) { 4704 mProbeStatusSinceLastUpdate = 4705 android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS; 4706 mProbeElapsedTimeSinceLastUpdateMs = elapsedTimeMs; 4707 4708 mLinkProbeSuccessSecondsSinceLastTxSuccessHistogram.increment( 4709 (int) (timeSinceLastTxSuccessMs / 1000)); 4710 mLinkProbeSuccessRssiCounts.increment(rssi); 4711 mLinkProbeSuccessLinkSpeedCounts.increment(linkSpeed); 4712 mLinkProbeSuccessElapsedTimeMsHistogram.increment(elapsedTimeMs); 4713 4714 if (mLinkProbeStaEventCount < MAX_LINK_PROBE_STA_EVENTS) { 4715 StaEvent event = new StaEvent(); 4716 event.type = StaEvent.TYPE_LINK_PROBE; 4717 event.linkProbeWasSuccess = true; 4718 event.linkProbeSuccessElapsedTimeMs = elapsedTimeMs; 4719 addStaEvent(event); 4720 } 4721 mLinkProbeStaEventCount++; 4722 } 4723 } 4724 4725 /** 4726 * Reports stats for an unsuccessful link probe. 4727 * 4728 * @param timeSinceLastTxSuccessMs At {@code startTimestampMs}, the number of milliseconds since 4729 * the last Tx success (according to 4730 * {@link WifiInfo#txSuccess}). 4731 * @param rssi The Rx RSSI at {@code startTimestampMs}. 4732 * @param linkSpeed The Tx link speed in Mbps at {@code startTimestampMs}. 4733 * @param reason The error code for the failure. See {@link WifiNative.SendMgmtFrameError}. 4734 */ 4735 public void logLinkProbeFailure(long timeSinceLastTxSuccessMs, 4736 int rssi, int linkSpeed, @WifiNative.SendMgmtFrameError int reason) { 4737 synchronized (mLock) { 4738 mProbeStatusSinceLastUpdate = 4739 android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE; 4740 mProbeElapsedTimeSinceLastUpdateMs = Integer.MAX_VALUE; 4741 4742 mLinkProbeFailureSecondsSinceLastTxSuccessHistogram.increment( 4743 (int) (timeSinceLastTxSuccessMs / 1000)); 4744 mLinkProbeFailureRssiCounts.increment(rssi); 4745 mLinkProbeFailureLinkSpeedCounts.increment(linkSpeed); 4746 mLinkProbeFailureReasonCounts.increment(reason); 4747 4748 if (mLinkProbeStaEventCount < MAX_LINK_PROBE_STA_EVENTS) { 4749 StaEvent event = new StaEvent(); 4750 event.type = StaEvent.TYPE_LINK_PROBE; 4751 event.linkProbeWasSuccess = false; 4752 event.linkProbeFailureReason = linkProbeFailureReasonToProto(reason); 4753 addStaEvent(event); 4754 } 4755 mLinkProbeStaEventCount++; 4756 } 4757 } 4758 4759 /** 4760 * Increments the number of probes triggered by the experiment `experimentId`. 4761 */ 4762 public void incrementLinkProbeExperimentProbeCount(String experimentId) { 4763 synchronized (mLock) { 4764 mLinkProbeExperimentProbeCounts.increment(experimentId); 4765 } 4766 } 4767 4768 /** 4769 * Update wifi config store read duration. 4770 * 4771 * @param timeMs Time it took to complete the operation, in milliseconds 4772 */ 4773 public void noteWifiConfigStoreReadDuration(int timeMs) { 4774 synchronized (mLock) { 4775 MetricsUtils.addValueToLinearHistogram(timeMs, mWifiConfigStoreReadDurationHistogram, 4776 WIFI_CONFIG_STORE_IO_DURATION_BUCKET_RANGES_MS); 4777 } 4778 } 4779 4780 /** 4781 * Update wifi config store write duration. 4782 * 4783 * @param timeMs Time it took to complete the operation, in milliseconds 4784 */ 4785 public void noteWifiConfigStoreWriteDuration(int timeMs) { 4786 synchronized (mLock) { 4787 MetricsUtils.addValueToLinearHistogram(timeMs, mWifiConfigStoreWriteDurationHistogram, 4788 WIFI_CONFIG_STORE_IO_DURATION_BUCKET_RANGES_MS); 4789 } 4790 } 4791 4792 /** 4793 * Logs the decision of a network selection algorithm when compared against another network 4794 * selection algorithm. 4795 * 4796 * @param experiment1Id ID of one experiment 4797 * @param experiment2Id ID of the other experiment 4798 * @param isSameDecision did the 2 experiments make the same decision? 4799 * @param numNetworkChoices the number of non-null network choices there were, where the null 4800 * choice is not selecting any network 4801 */ 4802 public void logNetworkSelectionDecision(int experiment1Id, int experiment2Id, 4803 boolean isSameDecision, int numNetworkChoices) { 4804 if (numNetworkChoices < 0) { 4805 Log.e(TAG, "numNetworkChoices cannot be negative!"); 4806 return; 4807 } 4808 if (experiment1Id == experiment2Id) { 4809 Log.e(TAG, "comparing the same experiment id: " + experiment1Id); 4810 return; 4811 } 4812 4813 Pair<Integer, Integer> key = new Pair<>(experiment1Id, experiment2Id); 4814 synchronized (mLock) { 4815 NetworkSelectionExperimentResults results = 4816 mNetworkSelectionExperimentPairNumChoicesCounts 4817 .computeIfAbsent(key, k -> new NetworkSelectionExperimentResults()); 4818 4819 IntCounter counter = isSameDecision 4820 ? results.sameSelectionNumChoicesCounter 4821 : results.differentSelectionNumChoicesCounter; 4822 4823 counter.increment(numNetworkChoices); 4824 } 4825 } 4826 4827 /** Increment number of network request API usage stats */ 4828 public void incrementNetworkRequestApiNumRequest() { 4829 synchronized (mLock) { 4830 mWifiNetworkRequestApiLog.numRequest++; 4831 } 4832 } 4833 4834 /** Add to the network request API match size histogram */ 4835 public void incrementNetworkRequestApiMatchSizeHistogram(int matchSize) { 4836 synchronized (mLock) { 4837 mWifiNetworkRequestApiMatchSizeHistogram.increment(matchSize); 4838 } 4839 } 4840 4841 /** Increment number of connection success via network request API */ 4842 public void incrementNetworkRequestApiNumConnectSuccess() { 4843 synchronized (mLock) { 4844 mWifiNetworkRequestApiLog.numConnectSuccess++; 4845 } 4846 } 4847 4848 /** Increment number of requests that bypassed user approval via network request API */ 4849 public void incrementNetworkRequestApiNumUserApprovalBypass() { 4850 synchronized (mLock) { 4851 mWifiNetworkRequestApiLog.numUserApprovalBypass++; 4852 } 4853 } 4854 4855 /** Increment number of requests that user rejected via network request API */ 4856 public void incrementNetworkRequestApiNumUserReject() { 4857 synchronized (mLock) { 4858 mWifiNetworkRequestApiLog.numUserReject++; 4859 } 4860 } 4861 4862 /** Increment number of requests from unique apps via network request API */ 4863 public void incrementNetworkRequestApiNumApps() { 4864 synchronized (mLock) { 4865 mWifiNetworkRequestApiLog.numApps++; 4866 } 4867 } 4868 4869 /** Increment number of network suggestion API modification by app stats */ 4870 public void incrementNetworkSuggestionApiNumModification() { 4871 synchronized (mLock) { 4872 mWifiNetworkSuggestionApiLog.numModification++; 4873 } 4874 } 4875 4876 /** Increment number of connection success via network suggestion API */ 4877 public void incrementNetworkSuggestionApiNumConnectSuccess() { 4878 synchronized (mLock) { 4879 mWifiNetworkSuggestionApiLog.numConnectSuccess++; 4880 } 4881 } 4882 4883 /** Increment number of connection failure via network suggestion API */ 4884 public void incrementNetworkSuggestionApiNumConnectFailure() { 4885 synchronized (mLock) { 4886 mWifiNetworkSuggestionApiLog.numConnectFailure++; 4887 } 4888 } 4889 4890 /** Clear and set the latest network suggestion API max list size histogram */ 4891 public void noteNetworkSuggestionApiListSizeHistogram(List<Integer> listSizes) { 4892 synchronized (mLock) { 4893 mWifiNetworkSuggestionApiListSizeHistogram.clear(); 4894 for (Integer listSize : listSizes) { 4895 mWifiNetworkSuggestionApiListSizeHistogram.increment(listSize); 4896 } 4897 } 4898 } 4899 4900 /** 4901 * Sets the nominator for a network (i.e. which entity made the suggestion to connect) 4902 * @param networkId the ID of the network, from its {@link WifiConfiguration} 4903 * @param nominatorId the entity that made the suggestion to connect to this network, 4904 * from {@link WifiMetricsProto.ConnectionEvent.ConnectionNominator} 4905 */ 4906 public void setNominatorForNetwork(int networkId, int nominatorId) { 4907 synchronized (mLock) { 4908 if (networkId == WifiConfiguration.INVALID_NETWORK_ID) return; 4909 mNetworkIdToNominatorId.put(networkId, nominatorId); 4910 } 4911 } 4912 4913 /** 4914 * Sets the numeric CandidateScorer id. 4915 */ 4916 public void setNetworkSelectorExperimentId(int expId) { 4917 synchronized (mLock) { 4918 mNetworkSelectorExperimentId = expId; 4919 } 4920 } 4921 4922 /** Add a WifiLock acqusition session */ 4923 public void addWifiLockAcqSession(int lockType, long duration) { 4924 switch (lockType) { 4925 case WifiManager.WIFI_MODE_FULL_HIGH_PERF: 4926 mWifiLockHighPerfAcqDurationSecHistogram.increment((int) (duration / 1000)); 4927 break; 4928 4929 case WifiManager.WIFI_MODE_FULL_LOW_LATENCY: 4930 mWifiLockLowLatencyAcqDurationSecHistogram.increment((int) (duration / 1000)); 4931 break; 4932 4933 default: 4934 Log.e(TAG, "addWifiLockAcqSession: Invalid lock type: " + lockType); 4935 break; 4936 } 4937 } 4938 4939 /** Add a WifiLock active session */ 4940 public void addWifiLockActiveSession(int lockType, long duration) { 4941 switch (lockType) { 4942 case WifiManager.WIFI_MODE_FULL_HIGH_PERF: 4943 mWifiLockStats.highPerfActiveTimeMs += duration; 4944 mWifiLockHighPerfActiveSessionDurationSecHistogram.increment( 4945 (int) (duration / 1000)); 4946 break; 4947 4948 case WifiManager.WIFI_MODE_FULL_LOW_LATENCY: 4949 mWifiLockStats.lowLatencyActiveTimeMs += duration; 4950 mWifiLockLowLatencyActiveSessionDurationSecHistogram.increment( 4951 (int) (duration / 1000)); 4952 break; 4953 4954 default: 4955 Log.e(TAG, "addWifiLockActiveSession: Invalid lock type: " + lockType); 4956 break; 4957 } 4958 } 4959 4960 /** Increments metrics counting number of addOrUpdateNetwork calls. **/ 4961 public void incrementNumAddOrUpdateNetworkCalls() { 4962 synchronized (mLock) { 4963 mWifiLogProto.numAddOrUpdateNetworkCalls++; 4964 } 4965 } 4966 4967 /** Increments metrics counting number of enableNetwork calls. **/ 4968 public void incrementNumEnableNetworkCalls() { 4969 synchronized (mLock) { 4970 mWifiLogProto.numEnableNetworkCalls++; 4971 } 4972 } 4973 4974 /** Add to WifiToggleStats **/ 4975 public void incrementNumWifiToggles(boolean isPrivileged, boolean enable) { 4976 synchronized (mLock) { 4977 if (isPrivileged && enable) { 4978 mWifiToggleStats.numToggleOnPrivileged++; 4979 } else if (isPrivileged && !enable) { 4980 mWifiToggleStats.numToggleOffPrivileged++; 4981 } else if (!isPrivileged && enable) { 4982 mWifiToggleStats.numToggleOnNormal++; 4983 } else { 4984 mWifiToggleStats.numToggleOffNormal++; 4985 } 4986 } 4987 } 4988 4989 /** 4990 * Increment number of passpoint provision failure 4991 * @param failureCode indicates error condition 4992 */ 4993 public void incrementPasspointProvisionFailure(int failureCode) { 4994 int provisionFailureCode; 4995 synchronized (mLock) { 4996 switch (failureCode) { 4997 case ProvisioningCallback.OSU_FAILURE_AP_CONNECTION: 4998 provisionFailureCode = PasspointProvisionStats.OSU_FAILURE_AP_CONNECTION; 4999 break; 5000 case ProvisioningCallback.OSU_FAILURE_SERVER_URL_INVALID: 5001 provisionFailureCode = PasspointProvisionStats.OSU_FAILURE_SERVER_URL_INVALID; 5002 break; 5003 case ProvisioningCallback.OSU_FAILURE_SERVER_CONNECTION: 5004 provisionFailureCode = PasspointProvisionStats.OSU_FAILURE_SERVER_CONNECTION; 5005 break; 5006 case ProvisioningCallback.OSU_FAILURE_SERVER_VALIDATION: 5007 provisionFailureCode = PasspointProvisionStats.OSU_FAILURE_SERVER_VALIDATION; 5008 break; 5009 case ProvisioningCallback.OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION: 5010 provisionFailureCode = PasspointProvisionStats 5011 .OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION; 5012 break; 5013 case ProvisioningCallback.OSU_FAILURE_PROVISIONING_ABORTED: 5014 provisionFailureCode = PasspointProvisionStats.OSU_FAILURE_PROVISIONING_ABORTED; 5015 break; 5016 case ProvisioningCallback.OSU_FAILURE_PROVISIONING_NOT_AVAILABLE: 5017 provisionFailureCode = PasspointProvisionStats 5018 .OSU_FAILURE_PROVISIONING_NOT_AVAILABLE; 5019 break; 5020 case ProvisioningCallback.OSU_FAILURE_INVALID_URL_FORMAT_FOR_OSU: 5021 provisionFailureCode = PasspointProvisionStats 5022 .OSU_FAILURE_INVALID_URL_FORMAT_FOR_OSU; 5023 break; 5024 case ProvisioningCallback.OSU_FAILURE_UNEXPECTED_COMMAND_TYPE: 5025 provisionFailureCode = PasspointProvisionStats 5026 .OSU_FAILURE_UNEXPECTED_COMMAND_TYPE; 5027 break; 5028 case ProvisioningCallback.OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_TYPE: 5029 provisionFailureCode = PasspointProvisionStats 5030 .OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_TYPE; 5031 break; 5032 case ProvisioningCallback.OSU_FAILURE_SOAP_MESSAGE_EXCHANGE: 5033 provisionFailureCode = PasspointProvisionStats 5034 .OSU_FAILURE_SOAP_MESSAGE_EXCHANGE; 5035 break; 5036 case ProvisioningCallback.OSU_FAILURE_START_REDIRECT_LISTENER: 5037 provisionFailureCode = PasspointProvisionStats 5038 .OSU_FAILURE_START_REDIRECT_LISTENER; 5039 break; 5040 case ProvisioningCallback.OSU_FAILURE_TIMED_OUT_REDIRECT_LISTENER: 5041 provisionFailureCode = PasspointProvisionStats 5042 .OSU_FAILURE_TIMED_OUT_REDIRECT_LISTENER; 5043 break; 5044 case ProvisioningCallback.OSU_FAILURE_NO_OSU_ACTIVITY_FOUND: 5045 provisionFailureCode = PasspointProvisionStats 5046 .OSU_FAILURE_NO_OSU_ACTIVITY_FOUND; 5047 break; 5048 case ProvisioningCallback.OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_STATUS: 5049 provisionFailureCode = PasspointProvisionStats 5050 .OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_STATUS; 5051 break; 5052 case ProvisioningCallback.OSU_FAILURE_NO_PPS_MO: 5053 provisionFailureCode = PasspointProvisionStats.OSU_FAILURE_NO_PPS_MO; 5054 break; 5055 case ProvisioningCallback.OSU_FAILURE_NO_AAA_SERVER_TRUST_ROOT_NODE: 5056 provisionFailureCode = PasspointProvisionStats 5057 .OSU_FAILURE_NO_AAA_SERVER_TRUST_ROOT_NODE; 5058 break; 5059 case ProvisioningCallback.OSU_FAILURE_NO_REMEDIATION_SERVER_TRUST_ROOT_NODE: 5060 provisionFailureCode = PasspointProvisionStats 5061 .OSU_FAILURE_NO_REMEDIATION_SERVER_TRUST_ROOT_NODE; 5062 break; 5063 case ProvisioningCallback.OSU_FAILURE_NO_POLICY_SERVER_TRUST_ROOT_NODE: 5064 provisionFailureCode = PasspointProvisionStats 5065 .OSU_FAILURE_NO_POLICY_SERVER_TRUST_ROOT_NODE; 5066 break; 5067 case ProvisioningCallback.OSU_FAILURE_RETRIEVE_TRUST_ROOT_CERTIFICATES: 5068 provisionFailureCode = PasspointProvisionStats 5069 .OSU_FAILURE_RETRIEVE_TRUST_ROOT_CERTIFICATES; 5070 break; 5071 case ProvisioningCallback.OSU_FAILURE_NO_AAA_TRUST_ROOT_CERTIFICATE: 5072 provisionFailureCode = PasspointProvisionStats 5073 .OSU_FAILURE_NO_AAA_TRUST_ROOT_CERTIFICATE; 5074 break; 5075 case ProvisioningCallback.OSU_FAILURE_ADD_PASSPOINT_CONFIGURATION: 5076 provisionFailureCode = PasspointProvisionStats 5077 .OSU_FAILURE_ADD_PASSPOINT_CONFIGURATION; 5078 break; 5079 case ProvisioningCallback.OSU_FAILURE_OSU_PROVIDER_NOT_FOUND: 5080 provisionFailureCode = PasspointProvisionStats 5081 .OSU_FAILURE_OSU_PROVIDER_NOT_FOUND; 5082 break; 5083 default: 5084 provisionFailureCode = PasspointProvisionStats.OSU_FAILURE_UNKNOWN; 5085 } 5086 mPasspointProvisionFailureCounts.increment(provisionFailureCode); 5087 } 5088 } 5089 5090 /** 5091 * Increment number of passpoint provision success 5092 */ 5093 public void incrementPasspointProvisionSuccess() { 5094 synchronized (mLock) { 5095 mNumProvisionSuccess++; 5096 } 5097 } 5098 } 5099