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