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 android.net.wifi.WifiConfiguration.MeteredOverride; 20 21 import static java.lang.StrictMath.toIntExact; 22 23 import android.content.Context; 24 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback; 25 import android.net.wifi.EAPConstants; 26 import android.net.wifi.IOnWifiUsabilityStatsListener; 27 import android.net.wifi.ScanResult; 28 import android.net.wifi.SoftApCapability; 29 import android.net.wifi.SoftApConfiguration; 30 import android.net.wifi.SupplicantState; 31 import android.net.wifi.WifiConfiguration; 32 import android.net.wifi.WifiConfiguration.NetworkSelectionStatus; 33 import android.net.wifi.WifiEnterpriseConfig; 34 import android.net.wifi.WifiInfo; 35 import android.net.wifi.WifiManager; 36 import android.net.wifi.WifiManager.DeviceMobilityState; 37 import android.net.wifi.WifiUsabilityStatsEntry.ProbeStatus; 38 import android.net.wifi.hotspot2.PasspointConfiguration; 39 import android.net.wifi.hotspot2.ProvisioningCallback; 40 import android.net.wifi.nl80211.WifiNl80211Manager; 41 import android.os.Handler; 42 import android.os.IBinder; 43 import android.os.Looper; 44 import android.os.Message; 45 import android.os.RemoteException; 46 import android.os.SystemProperties; 47 import android.telephony.TelephonyManager; 48 import android.text.TextUtils; 49 import android.util.ArrayMap; 50 import android.util.Base64; 51 import android.util.Log; 52 import android.util.Pair; 53 import android.util.SparseArray; 54 import android.util.SparseIntArray; 55 56 import com.android.internal.annotations.VisibleForTesting; 57 import com.android.server.wifi.aware.WifiAwareMetrics; 58 import com.android.server.wifi.hotspot2.ANQPNetworkKey; 59 import com.android.server.wifi.hotspot2.NetworkDetail; 60 import com.android.server.wifi.hotspot2.PasspointManager; 61 import com.android.server.wifi.hotspot2.PasspointMatch; 62 import com.android.server.wifi.hotspot2.PasspointProvider; 63 import com.android.server.wifi.hotspot2.Utils; 64 import com.android.server.wifi.p2p.WifiP2pMetrics; 65 import com.android.server.wifi.proto.WifiStatsLog; 66 import com.android.server.wifi.proto.nano.WifiMetricsProto; 67 import com.android.server.wifi.proto.nano.WifiMetricsProto.CarrierWifiMetrics; 68 import com.android.server.wifi.proto.nano.WifiMetricsProto.ConnectToNetworkNotificationAndActionCount; 69 import com.android.server.wifi.proto.nano.WifiMetricsProto.DeviceMobilityStatePnoScanStats; 70 import com.android.server.wifi.proto.nano.WifiMetricsProto.ExperimentValues; 71 import com.android.server.wifi.proto.nano.WifiMetricsProto.HealthMonitorMetrics; 72 import com.android.server.wifi.proto.nano.WifiMetricsProto.InitPartialScanStats; 73 import com.android.server.wifi.proto.nano.WifiMetricsProto.LinkProbeStats; 74 import com.android.server.wifi.proto.nano.WifiMetricsProto.LinkProbeStats.ExperimentProbeCounts; 75 import com.android.server.wifi.proto.nano.WifiMetricsProto.LinkProbeStats.LinkProbeFailureReasonCount; 76 import com.android.server.wifi.proto.nano.WifiMetricsProto.LinkSpeedCount; 77 import com.android.server.wifi.proto.nano.WifiMetricsProto.MeteredNetworkStats; 78 import com.android.server.wifi.proto.nano.WifiMetricsProto.NetworkDisableReason; 79 import com.android.server.wifi.proto.nano.WifiMetricsProto.NetworkSelectionExperimentDecisions; 80 import com.android.server.wifi.proto.nano.WifiMetricsProto.PasspointProfileTypeCount; 81 import com.android.server.wifi.proto.nano.WifiMetricsProto.PasspointProvisionStats; 82 import com.android.server.wifi.proto.nano.WifiMetricsProto.PasspointProvisionStats.ProvisionFailureCount; 83 import com.android.server.wifi.proto.nano.WifiMetricsProto.PnoScanMetrics; 84 import com.android.server.wifi.proto.nano.WifiMetricsProto.SoftApConnectedClientsEvent; 85 import com.android.server.wifi.proto.nano.WifiMetricsProto.StaEvent; 86 import com.android.server.wifi.proto.nano.WifiMetricsProto.StaEvent.ConfigInfo; 87 import com.android.server.wifi.proto.nano.WifiMetricsProto.TargetNetworkInfo; 88 import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent; 89 import com.android.server.wifi.proto.nano.WifiMetricsProto.UserReactionToApprovalUiEvent; 90 import com.android.server.wifi.proto.nano.WifiMetricsProto.UserReactionToApprovalUiEvent.UserReaction; 91 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiIsUnusableEvent; 92 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiLinkLayerUsageStats; 93 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiLockStats; 94 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiNetworkRequestApiLog; 95 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiNetworkSuggestionApiLog; 96 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiNetworkSuggestionApiLog.SuggestionAppCount; 97 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiStatus; 98 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiToggleStats; 99 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiUsabilityStats; 100 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiUsabilityStatsEntry; 101 import com.android.server.wifi.rtt.RttMetrics; 102 import com.android.server.wifi.scanner.KnownBandsChannelHelper; 103 import com.android.server.wifi.util.ExternalCallbackTracker; 104 import com.android.server.wifi.util.InformationElementUtil; 105 import com.android.server.wifi.util.IntCounter; 106 import com.android.server.wifi.util.IntHistogram; 107 import com.android.server.wifi.util.MetricsUtils; 108 import com.android.server.wifi.util.ObjectCounter; 109 import com.android.server.wifi.util.ScanResultUtil; 110 import com.android.wifi.resources.R; 111 112 import org.json.JSONArray; 113 import org.json.JSONException; 114 import org.json.JSONObject; 115 116 import java.io.FileDescriptor; 117 import java.io.PrintWriter; 118 import java.util.ArrayList; 119 import java.util.Arrays; 120 import java.util.BitSet; 121 import java.util.Calendar; 122 import java.util.HashMap; 123 import java.util.HashSet; 124 import java.util.LinkedList; 125 import java.util.List; 126 import java.util.Map; 127 import java.util.Random; 128 import java.util.Set; 129 130 /** 131 * Provides storage for wireless connectivity metrics, as they are generated. 132 * Metrics logged by this class include: 133 * Aggregated connection stats (num of connections, num of failures, ...) 134 * Discrete connection event stats (time, duration, failure codes, ...) 135 * Router details (technology type, authentication type, ...) 136 * Scan stats 137 */ 138 public class WifiMetrics { 139 private static final String TAG = "WifiMetrics"; 140 private static final boolean DBG = false; 141 /** 142 * Clamp the RSSI poll counts to values between [MIN,MAX]_RSSI_POLL 143 */ 144 private static final int MAX_RSSI_POLL = 0; 145 private static final int MIN_RSSI_POLL = -127; 146 public static final int MAX_RSSI_DELTA = 127; 147 public static final int MIN_RSSI_DELTA = -127; 148 /** Minimum link speed (Mbps) to count for link_speed_counts */ 149 public static final int MIN_LINK_SPEED_MBPS = 0; 150 /** Maximum time period between ScanResult and RSSI poll to generate rssi delta datapoint */ 151 public static final long TIMEOUT_RSSI_DELTA_MILLIS = 3000; 152 private static final int MIN_WIFI_SCORE = 0; 153 private static final int MAX_WIFI_SCORE = ConnectedScore.WIFI_MAX_SCORE; 154 private static final int MIN_WIFI_USABILITY_SCORE = 0; // inclusive 155 private static final int MAX_WIFI_USABILITY_SCORE = 100; // inclusive 156 @VisibleForTesting 157 static final int LOW_WIFI_SCORE = 50; // Mobile data score 158 @VisibleForTesting 159 static final int LOW_WIFI_USABILITY_SCORE = 50; // Mobile data score 160 private final Object mLock = new Object(); 161 private static final int MAX_CONNECTION_EVENTS = 256; 162 // Largest bucket in the NumConnectableNetworkCount histogram, 163 // anything large will be stored in this bucket 164 public static final int MAX_CONNECTABLE_SSID_NETWORK_BUCKET = 20; 165 public static final int MAX_CONNECTABLE_BSSID_NETWORK_BUCKET = 50; 166 public static final int MAX_TOTAL_SCAN_RESULT_SSIDS_BUCKET = 100; 167 public static final int MAX_TOTAL_SCAN_RESULTS_BUCKET = 250; 168 public static final int MAX_TOTAL_PASSPOINT_APS_BUCKET = 50; 169 public static final int MAX_TOTAL_PASSPOINT_UNIQUE_ESS_BUCKET = 20; 170 public static final int MAX_PASSPOINT_APS_PER_UNIQUE_ESS_BUCKET = 50; 171 public static final int MAX_TOTAL_80211MC_APS_BUCKET = 20; 172 private static final int CONNECT_TO_NETWORK_NOTIFICATION_ACTION_KEY_MULTIPLIER = 1000; 173 // Max limit for number of soft AP related events, extra events will be dropped. 174 private static final int MAX_NUM_SOFT_AP_EVENTS = 256; 175 // Maximum number of WifiIsUnusableEvent 176 public static final int MAX_UNUSABLE_EVENTS = 20; 177 // Minimum time wait before generating next WifiIsUnusableEvent from data stall 178 public static final int MIN_DATA_STALL_WAIT_MS = 120 * 1000; // 2 minutes 179 // Max number of WifiUsabilityStatsEntry elements to store in the ringbuffer. 180 public static final int MAX_WIFI_USABILITY_STATS_ENTRIES_LIST_SIZE = 40; 181 // Max number of WifiUsabilityStats elements to store for each type. 182 public static final int MAX_WIFI_USABILITY_STATS_LIST_SIZE_PER_TYPE = 10; 183 // Max number of WifiUsabilityStats per labeled type to upload to server 184 public static final int MAX_WIFI_USABILITY_STATS_PER_TYPE_TO_UPLOAD = 2; 185 public static final int NUM_WIFI_USABILITY_STATS_ENTRIES_PER_WIFI_GOOD = 100; 186 public static final int MIN_WIFI_GOOD_USABILITY_STATS_PERIOD_MS = 1000 * 3600; // 1 hour 187 // Histogram for WifiConfigStore IO duration times. Indicates the following 5 buckets (in ms): 188 // < 50 189 // [50, 100) 190 // [100, 150) 191 // [150, 200) 192 // [200, 300) 193 // >= 300 194 private static final int[] WIFI_CONFIG_STORE_IO_DURATION_BUCKET_RANGES_MS = 195 {50, 100, 150, 200, 300}; 196 // Minimum time wait before generating a LABEL_GOOD stats after score breaching low. 197 public static final int MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS = 60 * 1000; // 1 minute 198 // Maximum time that a score breaching low event stays valid. 199 public static final int VALIDITY_PERIOD_OF_SCORE_BREACH_LOW_MS = 90 * 1000; // 1.5 minutes 200 201 private Clock mClock; 202 private boolean mScreenOn; 203 private int mWifiState; 204 private WifiAwareMetrics mWifiAwareMetrics; 205 private RttMetrics mRttMetrics; 206 private final PnoScanMetrics mPnoScanMetrics = new PnoScanMetrics(); 207 private final WifiLinkLayerUsageStats mWifiLinkLayerUsageStats = new WifiLinkLayerUsageStats(); 208 private final ExperimentValues mExperimentValues = new ExperimentValues(); 209 private Handler mHandler; 210 private ScoringParams mScoringParams; 211 private WifiConfigManager mWifiConfigManager; 212 private BssidBlocklistMonitor mBssidBlocklistMonitor; 213 private WifiNetworkSelector mWifiNetworkSelector; 214 private PasspointManager mPasspointManager; 215 private Context mContext; 216 private FrameworkFacade mFacade; 217 private WifiDataStall mWifiDataStall; 218 private WifiLinkLayerStats mLastLinkLayerStats; 219 private WifiHealthMonitor mWifiHealthMonitor; 220 private WifiScoreCard mWifiScoreCard; 221 private String mLastBssid; 222 private int mLastFrequency = -1; 223 private int mSeqNumInsideFramework = 0; 224 private int mLastWifiUsabilityScore = -1; 225 private int mLastWifiUsabilityScoreNoReset = -1; 226 private int mLastPredictionHorizonSec = -1; 227 private int mLastPredictionHorizonSecNoReset = -1; 228 private int mSeqNumToFramework = -1; 229 @ProbeStatus private int mProbeStatusSinceLastUpdate = 230 android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE; 231 private int mProbeElapsedTimeSinceLastUpdateMs = -1; 232 private int mProbeMcsRateSinceLastUpdate = -1; 233 private long mScoreBreachLowTimeMillis = -1; 234 235 public static final int MAX_STA_EVENTS = 768; 236 @VisibleForTesting static final int MAX_USER_ACTION_EVENTS = 200; 237 private LinkedList<StaEventWithTime> mStaEventList = new LinkedList<>(); 238 private LinkedList<UserActionEventWithTime> mUserActionEventList = new LinkedList<>(); 239 private WifiStatusBuilder mWifiStatusBuilder = new WifiStatusBuilder(); 240 private int mLastPollRssi = -127; 241 private int mLastPollLinkSpeed = -1; 242 private int mLastPollRxLinkSpeed = -1; 243 private int mLastPollFreq = -1; 244 private int mLastScore = -1; 245 private boolean mAdaptiveConnectivityEnabled = true; 246 247 /** 248 * Metrics are stored within an instance of the WifiLog proto during runtime, 249 * The ConnectionEvent, SystemStateEntries & ScanReturnEntries metrics are stored during 250 * runtime in member lists of this WifiMetrics class, with the final WifiLog proto being pieced 251 * together at dump-time 252 */ 253 private final WifiMetricsProto.WifiLog mWifiLogProto = new WifiMetricsProto.WifiLog(); 254 /** 255 * Session information that gets logged for every Wifi connection attempt. 256 */ 257 private final List<ConnectionEvent> mConnectionEventList = new ArrayList<>(); 258 /** 259 * The latest started (but un-ended) connection attempt 260 */ 261 private ConnectionEvent mCurrentConnectionEvent; 262 /** 263 * Count of number of times each scan return code, indexed by WifiLog.ScanReturnCode 264 */ 265 private final SparseIntArray mScanReturnEntries = new SparseIntArray(); 266 /** 267 * Mapping of system state to the counts of scans requested in that wifi state * screenOn 268 * combination. Indexed by WifiLog.WifiState * (1 + screenOn) 269 */ 270 private final SparseIntArray mWifiSystemStateEntries = new SparseIntArray(); 271 /** Mapping of channel frequency to its RSSI distribution histogram **/ 272 private final Map<Integer, SparseIntArray> mRssiPollCountsMap = new HashMap<>(); 273 /** Mapping of RSSI scan-poll delta values to counts. */ 274 private final SparseIntArray mRssiDeltaCounts = new SparseIntArray(); 275 /** Mapping of link speed values to LinkSpeedCount objects. */ 276 private final SparseArray<LinkSpeedCount> mLinkSpeedCounts = new SparseArray<>(); 277 278 private final IntCounter mTxLinkSpeedCount2g = new IntCounter(); 279 private final IntCounter mTxLinkSpeedCount5gLow = new IntCounter(); 280 private final IntCounter mTxLinkSpeedCount5gMid = new IntCounter(); 281 private final IntCounter mTxLinkSpeedCount5gHigh = new IntCounter(); 282 private final IntCounter mTxLinkSpeedCount6gLow = new IntCounter(); 283 private final IntCounter mTxLinkSpeedCount6gMid = new IntCounter(); 284 private final IntCounter mTxLinkSpeedCount6gHigh = new IntCounter(); 285 286 private final IntCounter mRxLinkSpeedCount2g = new IntCounter(); 287 private final IntCounter mRxLinkSpeedCount5gLow = new IntCounter(); 288 private final IntCounter mRxLinkSpeedCount5gMid = new IntCounter(); 289 private final IntCounter mRxLinkSpeedCount5gHigh = new IntCounter(); 290 private final IntCounter mRxLinkSpeedCount6gLow = new IntCounter(); 291 private final IntCounter mRxLinkSpeedCount6gMid = new IntCounter(); 292 private final IntCounter mRxLinkSpeedCount6gHigh = new IntCounter(); 293 294 /** RSSI of the scan result for the last connection event*/ 295 private int mScanResultRssi = 0; 296 /** Boot-relative timestamp when the last candidate scanresult was received, used to calculate 297 RSSI deltas. -1 designates no candidate scanResult being tracked */ 298 private long mScanResultRssiTimestampMillis = -1; 299 /** Mapping of alert reason to the respective alert count. */ 300 private final SparseIntArray mWifiAlertReasonCounts = new SparseIntArray(); 301 /** 302 * Records the getElapsedSinceBootMillis (in seconds) that represents the beginning of data 303 * capture for for this WifiMetricsProto 304 */ 305 private long mRecordStartTimeSec; 306 /** Mapping of Wifi Scores to counts */ 307 private final SparseIntArray mWifiScoreCounts = new SparseIntArray(); 308 /** Mapping of Wifi Usability Scores to counts */ 309 private final SparseIntArray mWifiUsabilityScoreCounts = new SparseIntArray(); 310 /** Mapping of SoftApManager start SoftAp return codes to counts */ 311 private final SparseIntArray mSoftApManagerReturnCodeCounts = new SparseIntArray(); 312 313 private final SparseIntArray mTotalSsidsInScanHistogram = new SparseIntArray(); 314 private final SparseIntArray mTotalBssidsInScanHistogram = new SparseIntArray(); 315 private final SparseIntArray mAvailableOpenSsidsInScanHistogram = new SparseIntArray(); 316 private final SparseIntArray mAvailableOpenBssidsInScanHistogram = new SparseIntArray(); 317 private final SparseIntArray mAvailableSavedSsidsInScanHistogram = new SparseIntArray(); 318 private final SparseIntArray mAvailableSavedBssidsInScanHistogram = new SparseIntArray(); 319 private final SparseIntArray mAvailableOpenOrSavedSsidsInScanHistogram = new SparseIntArray(); 320 private final SparseIntArray mAvailableOpenOrSavedBssidsInScanHistogram = new SparseIntArray(); 321 private final SparseIntArray mAvailableSavedPasspointProviderProfilesInScanHistogram = 322 new SparseIntArray(); 323 private final SparseIntArray mAvailableSavedPasspointProviderBssidsInScanHistogram = 324 new SparseIntArray(); 325 326 private final IntCounter mInstalledPasspointProfileTypeForR1 = new IntCounter(); 327 private final IntCounter mInstalledPasspointProfileTypeForR2 = new IntCounter(); 328 329 /** Mapping of "Connect to Network" notifications to counts. */ 330 private final SparseIntArray mConnectToNetworkNotificationCount = new SparseIntArray(); 331 /** Mapping of "Connect to Network" notification user actions to counts. */ 332 private final SparseIntArray mConnectToNetworkNotificationActionCount = new SparseIntArray(); 333 private int mOpenNetworkRecommenderBlacklistSize = 0; 334 private boolean mIsWifiNetworksAvailableNotificationOn = false; 335 private int mNumOpenNetworkConnectMessageFailedToSend = 0; 336 private int mNumOpenNetworkRecommendationUpdates = 0; 337 /** List of soft AP events related to number of connected clients in tethered mode */ 338 private final List<SoftApConnectedClientsEvent> mSoftApEventListTethered = new ArrayList<>(); 339 /** List of soft AP events related to number of connected clients in local only mode */ 340 private final List<SoftApConnectedClientsEvent> mSoftApEventListLocalOnly = new ArrayList<>(); 341 342 private final SparseIntArray mObservedHotspotR1ApInScanHistogram = new SparseIntArray(); 343 private final SparseIntArray mObservedHotspotR2ApInScanHistogram = new SparseIntArray(); 344 private final SparseIntArray mObservedHotspotR3ApInScanHistogram = new SparseIntArray(); 345 private final SparseIntArray mObservedHotspotR1EssInScanHistogram = new SparseIntArray(); 346 private final SparseIntArray mObservedHotspotR2EssInScanHistogram = new SparseIntArray(); 347 private final SparseIntArray mObservedHotspotR3EssInScanHistogram = new SparseIntArray(); 348 private final SparseIntArray mObservedHotspotR1ApsPerEssInScanHistogram = new SparseIntArray(); 349 private final SparseIntArray mObservedHotspotR2ApsPerEssInScanHistogram = new SparseIntArray(); 350 private final SparseIntArray mObservedHotspotR3ApsPerEssInScanHistogram = new SparseIntArray(); 351 352 private final SparseIntArray mObserved80211mcApInScanHistogram = new SparseIntArray(); 353 354 // link probing stats 355 private final IntCounter mLinkProbeSuccessRssiCounts = new IntCounter(-85, -65); 356 private final IntCounter mLinkProbeFailureRssiCounts = new IntCounter(-85, -65); 357 private final IntCounter mLinkProbeSuccessLinkSpeedCounts = new IntCounter(); 358 private final IntCounter mLinkProbeFailureLinkSpeedCounts = new IntCounter(); 359 360 private static final int[] LINK_PROBE_TIME_SINCE_LAST_TX_SUCCESS_SECONDS_HISTOGRAM_BUCKETS = 361 {5, 15, 45, 135}; 362 private final IntHistogram mLinkProbeSuccessSecondsSinceLastTxSuccessHistogram = 363 new IntHistogram(LINK_PROBE_TIME_SINCE_LAST_TX_SUCCESS_SECONDS_HISTOGRAM_BUCKETS); 364 private final IntHistogram mLinkProbeFailureSecondsSinceLastTxSuccessHistogram = 365 new IntHistogram(LINK_PROBE_TIME_SINCE_LAST_TX_SUCCESS_SECONDS_HISTOGRAM_BUCKETS); 366 367 private static final int[] LINK_PROBE_ELAPSED_TIME_MS_HISTOGRAM_BUCKETS = 368 {5, 10, 15, 20, 25, 50, 100, 200, 400, 800}; 369 private final IntHistogram mLinkProbeSuccessElapsedTimeMsHistogram = new IntHistogram( 370 LINK_PROBE_ELAPSED_TIME_MS_HISTOGRAM_BUCKETS); 371 private final IntCounter mLinkProbeFailureReasonCounts = new IntCounter(); 372 private final MeteredNetworkStatsBuilder mMeteredNetworkStatsBuilder = 373 new MeteredNetworkStatsBuilder(); 374 375 /** 376 * Maps a String link probe experiment ID to the number of link probes that were sent for this 377 * experiment. 378 */ 379 private final ObjectCounter<String> mLinkProbeExperimentProbeCounts = new ObjectCounter<>(); 380 private int mLinkProbeStaEventCount = 0; 381 @VisibleForTesting static final int MAX_LINK_PROBE_STA_EVENTS = MAX_STA_EVENTS / 4; 382 383 private final LinkedList<WifiUsabilityStatsEntry> mWifiUsabilityStatsEntriesList = 384 new LinkedList<>(); 385 private final LinkedList<WifiUsabilityStats> mWifiUsabilityStatsListBad = new LinkedList<>(); 386 private final LinkedList<WifiUsabilityStats> mWifiUsabilityStatsListGood = new LinkedList<>(); 387 private int mWifiUsabilityStatsCounter = 0; 388 private final Random mRand = new Random(); 389 private final ExternalCallbackTracker<IOnWifiUsabilityStatsListener> mOnWifiUsabilityListeners; 390 391 private final SparseArray<DeviceMobilityStatePnoScanStats> mMobilityStatePnoStatsMap = 392 new SparseArray<>(); 393 private int mCurrentDeviceMobilityState; 394 /** 395 * The timestamp of the start of the current device mobility state. 396 */ 397 private long mCurrentDeviceMobilityStateStartMs; 398 /** 399 * The timestamp of when the PNO scan started in the current device mobility state. 400 */ 401 private long mCurrentDeviceMobilityStatePnoScanStartMs; 402 403 /** Wifi power metrics*/ 404 private WifiPowerMetrics mWifiPowerMetrics; 405 406 /** Wifi Wake metrics */ 407 private final WifiWakeMetrics mWifiWakeMetrics = new WifiWakeMetrics(); 408 409 /** Wifi P2p metrics */ 410 private final WifiP2pMetrics mWifiP2pMetrics; 411 412 /** DPP */ 413 private final DppMetrics mDppMetrics; 414 415 /** WifiConfigStore read duration histogram. */ 416 private SparseIntArray mWifiConfigStoreReadDurationHistogram = new SparseIntArray(); 417 418 /** WifiConfigStore write duration histogram. */ 419 private SparseIntArray mWifiConfigStoreWriteDurationHistogram = new SparseIntArray(); 420 421 /** New API surface metrics */ 422 private final WifiNetworkRequestApiLog mWifiNetworkRequestApiLog = 423 new WifiNetworkRequestApiLog(); 424 private static final int[] NETWORK_REQUEST_API_MATCH_SIZE_HISTOGRAM_BUCKETS = 425 {0, 1, 5, 10}; 426 private final IntHistogram mWifiNetworkRequestApiMatchSizeHistogram = 427 new IntHistogram(NETWORK_REQUEST_API_MATCH_SIZE_HISTOGRAM_BUCKETS); 428 429 private final WifiNetworkSuggestionApiLog mWifiNetworkSuggestionApiLog = 430 new WifiNetworkSuggestionApiLog(); 431 private static final int[] NETWORK_SUGGESTION_API_LIST_SIZE_HISTOGRAM_BUCKETS = 432 {5, 20, 50, 100, 500}; 433 private final IntHistogram mWifiNetworkSuggestionApiListSizeHistogram = 434 new IntHistogram(NETWORK_SUGGESTION_API_LIST_SIZE_HISTOGRAM_BUCKETS); 435 private final IntCounter mWifiNetworkSuggestionApiAppTypeCounter = new IntCounter(); 436 private final List<UserReaction> mUserApprovalSuggestionAppUiReactionList = 437 new ArrayList<>(); 438 private final List<UserReaction> mUserApprovalCarrierUiReactionList = 439 new ArrayList<>(); 440 441 private final WifiLockStats mWifiLockStats = new WifiLockStats(); 442 private static final int[] WIFI_LOCK_SESSION_DURATION_HISTOGRAM_BUCKETS = 443 {1, 10, 60, 600, 3600}; 444 private final WifiToggleStats mWifiToggleStats = new WifiToggleStats(); 445 private BssidBlocklistStats mBssidBlocklistStats = new BssidBlocklistStats(); 446 447 private final IntHistogram mWifiLockHighPerfAcqDurationSecHistogram = 448 new IntHistogram(WIFI_LOCK_SESSION_DURATION_HISTOGRAM_BUCKETS); 449 private final IntHistogram mWifiLockLowLatencyAcqDurationSecHistogram = 450 new IntHistogram(WIFI_LOCK_SESSION_DURATION_HISTOGRAM_BUCKETS); 451 452 private final IntHistogram mWifiLockHighPerfActiveSessionDurationSecHistogram = 453 new IntHistogram(WIFI_LOCK_SESSION_DURATION_HISTOGRAM_BUCKETS); 454 private final IntHistogram mWifiLockLowLatencyActiveSessionDurationSecHistogram = 455 new IntHistogram(WIFI_LOCK_SESSION_DURATION_HISTOGRAM_BUCKETS); 456 457 /** 458 * (experiment1Id, experiment2Id) => 459 * (sameSelectionNumChoicesCounter, differentSelectionNumChoicesCounter) 460 */ 461 private Map<Pair<Integer, Integer>, NetworkSelectionExperimentResults> 462 mNetworkSelectionExperimentPairNumChoicesCounts = new ArrayMap<>(); 463 464 private int mNetworkSelectorExperimentId; 465 466 /** 467 * Tracks the nominator for each network (i.e. which entity made the suggestion to connect). 468 * This object should not be cleared. 469 */ 470 private final SparseIntArray mNetworkIdToNominatorId = new SparseIntArray(); 471 472 /** passpoint provision success count */ 473 private int mNumProvisionSuccess = 0; 474 475 /** Mapping of failure code to the respective passpoint provision failure count. */ 476 private final IntCounter mPasspointProvisionFailureCounts = new IntCounter(); 477 478 // Connection duration stats collected while link layer stats reports are on 479 private final ConnectionDurationStats mConnectionDurationStats = new ConnectionDurationStats(); 480 481 private static final int[] CHANNEL_UTILIZATION_BUCKETS = 482 {25, 50, 75, 100, 125, 150, 175, 200, 225}; 483 484 private final IntHistogram mChannelUtilizationHistogram2G = 485 new IntHistogram(CHANNEL_UTILIZATION_BUCKETS); 486 487 private final IntHistogram mChannelUtilizationHistogramAbove2G = 488 new IntHistogram(CHANNEL_UTILIZATION_BUCKETS); 489 490 private static final int[] THROUGHPUT_MBPS_BUCKETS = 491 {1, 5, 10, 15, 25, 50, 100, 150, 200, 300, 450, 600, 800, 1200, 1600}; 492 private final IntHistogram mTxThroughputMbpsHistogram2G = 493 new IntHistogram(THROUGHPUT_MBPS_BUCKETS); 494 private final IntHistogram mRxThroughputMbpsHistogram2G = 495 new IntHistogram(THROUGHPUT_MBPS_BUCKETS); 496 private final IntHistogram mTxThroughputMbpsHistogramAbove2G = 497 new IntHistogram(THROUGHPUT_MBPS_BUCKETS); 498 private final IntHistogram mRxThroughputMbpsHistogramAbove2G = 499 new IntHistogram(THROUGHPUT_MBPS_BUCKETS); 500 501 // Init partial scan metrics 502 private int mInitPartialScanTotalCount; 503 private int mInitPartialScanSuccessCount; 504 private int mInitPartialScanFailureCount; 505 private static final int[] INIT_PARTIAL_SCAN_HISTOGRAM_BUCKETS = 506 {1, 3, 5, 10}; 507 private final IntHistogram mInitPartialScanSuccessHistogram = 508 new IntHistogram(INIT_PARTIAL_SCAN_HISTOGRAM_BUCKETS); 509 private final IntHistogram mInitPartialScanFailureHistogram = 510 new IntHistogram(INIT_PARTIAL_SCAN_HISTOGRAM_BUCKETS); 511 512 // Wi-Fi off metrics 513 private final WifiOffMetrics mWifiOffMetrics = new WifiOffMetrics(); 514 515 private final SoftApConfigLimitationMetrics mSoftApConfigLimitationMetrics = 516 new SoftApConfigLimitationMetrics(); 517 518 private final CarrierWifiMetrics mCarrierWifiMetrics = 519 new CarrierWifiMetrics(); 520 521 @VisibleForTesting 522 static class NetworkSelectionExperimentResults { 523 public static final int MAX_CHOICES = 10; 524 525 public IntCounter sameSelectionNumChoicesCounter = new IntCounter(0, MAX_CHOICES); 526 public IntCounter differentSelectionNumChoicesCounter = new IntCounter(0, MAX_CHOICES); 527 528 @Override toString()529 public String toString() { 530 return "NetworkSelectionExperimentResults{" 531 + "sameSelectionNumChoicesCounter=" 532 + sameSelectionNumChoicesCounter 533 + ", differentSelectionNumChoicesCounter=" 534 + differentSelectionNumChoicesCounter 535 + '}'; 536 } 537 } 538 539 class RouterFingerPrint { 540 private WifiMetricsProto.RouterFingerPrint mRouterFingerPrintProto; RouterFingerPrint()541 RouterFingerPrint() { 542 mRouterFingerPrintProto = new WifiMetricsProto.RouterFingerPrint(); 543 } 544 toString()545 public String toString() { 546 StringBuilder sb = new StringBuilder(); 547 synchronized (mLock) { 548 sb.append("mConnectionEvent.roamType=" + mRouterFingerPrintProto.roamType); 549 sb.append(", mChannelInfo=" + mRouterFingerPrintProto.channelInfo); 550 sb.append(", mDtim=" + mRouterFingerPrintProto.dtim); 551 sb.append(", mAuthentication=" + mRouterFingerPrintProto.authentication); 552 sb.append(", mHidden=" + mRouterFingerPrintProto.hidden); 553 sb.append(", mRouterTechnology=" + mRouterFingerPrintProto.routerTechnology); 554 sb.append(", mSupportsIpv6=" + mRouterFingerPrintProto.supportsIpv6); 555 sb.append(", mEapMethod=" + mRouterFingerPrintProto.eapMethod); 556 sb.append(", mAuthPhase2Method=" + mRouterFingerPrintProto.authPhase2Method); 557 sb.append(", mOcspType=" + mRouterFingerPrintProto.ocspType); 558 sb.append(", mPmkCache=" + mRouterFingerPrintProto.pmkCacheEnabled); 559 sb.append(", mMaxSupportedTxLinkSpeedMbps=" + mRouterFingerPrintProto 560 .maxSupportedTxLinkSpeedMbps); 561 sb.append(", mMaxSupportedRxLinkSpeedMbps=" + mRouterFingerPrintProto 562 .maxSupportedRxLinkSpeedMbps); 563 } 564 return sb.toString(); 565 } updateFromWifiConfiguration(WifiConfiguration config)566 public void updateFromWifiConfiguration(WifiConfiguration config) { 567 synchronized (mLock) { 568 if (config != null) { 569 // Is this a hidden network 570 mRouterFingerPrintProto.hidden = config.hiddenSSID; 571 // Config may not have a valid dtimInterval set yet, in which case dtim will be zero 572 // (These are only populated from beacon frame scan results, which are returned as 573 // scan results from the chip far less frequently than Probe-responses) 574 if (config.dtimInterval > 0) { 575 mRouterFingerPrintProto.dtim = config.dtimInterval; 576 } 577 mCurrentConnectionEvent.mConfigSsid = config.SSID; 578 // Get AuthType information from config (We do this again from ScanResult after 579 // associating with BSSID) 580 if (config.allowedKeyManagement != null 581 && config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) { 582 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto 583 .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_OPEN; 584 } else if (config.isEnterprise()) { 585 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto 586 .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE; 587 } else { 588 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto 589 .authentication = WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL; 590 } 591 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto 592 .passpoint = config.isPasspoint(); 593 // If there's a ScanResult candidate associated with this config already, get it and 594 // log (more accurate) metrics from it 595 ScanResult candidate = config.getNetworkSelectionStatus().getCandidate(); 596 if (candidate != null) { 597 updateMetricsFromScanResult(candidate); 598 } 599 if (mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto 600 .authentication == WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE 601 && config.enterpriseConfig != null) { 602 int eapMethod = config.enterpriseConfig.getEapMethod(); 603 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto 604 .eapMethod = getEapMethodProto(eapMethod); 605 int phase2Method = config.enterpriseConfig.getPhase2Method(); 606 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto 607 .authPhase2Method = getAuthPhase2MethodProto(phase2Method); 608 int ocspType = config.enterpriseConfig.getOcsp(); 609 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto 610 .ocspType = getOcspTypeProto(ocspType); 611 } 612 } 613 } 614 } 615 setPmkCache(boolean isEnabled)616 public void setPmkCache(boolean isEnabled) { 617 synchronized (mLock) { 618 mRouterFingerPrintProto.pmkCacheEnabled = isEnabled; 619 } 620 } 621 setMaxSupportedLinkSpeedMbps(int maxSupportedTxLinkSpeedMbps, int maxSupportedRxLinkSpeedMbps)622 public void setMaxSupportedLinkSpeedMbps(int maxSupportedTxLinkSpeedMbps, 623 int maxSupportedRxLinkSpeedMbps) { 624 synchronized (mLock) { 625 mRouterFingerPrintProto.maxSupportedTxLinkSpeedMbps = maxSupportedTxLinkSpeedMbps; 626 mRouterFingerPrintProto.maxSupportedRxLinkSpeedMbps = maxSupportedRxLinkSpeedMbps; 627 } 628 } 629 } getEapMethodProto(int eapMethod)630 private int getEapMethodProto(int eapMethod) { 631 switch (eapMethod) { 632 case WifiEnterpriseConfig.Eap.WAPI_CERT: 633 return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_WAPI_CERT; 634 case WifiEnterpriseConfig.Eap.TLS: 635 return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_TLS; 636 case WifiEnterpriseConfig.Eap.UNAUTH_TLS: 637 return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_UNAUTH_TLS; 638 case WifiEnterpriseConfig.Eap.PEAP: 639 return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_PEAP; 640 case WifiEnterpriseConfig.Eap.PWD: 641 return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_PWD; 642 case WifiEnterpriseConfig.Eap.TTLS: 643 return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_TTLS; 644 case WifiEnterpriseConfig.Eap.SIM: 645 return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_SIM; 646 case WifiEnterpriseConfig.Eap.AKA: 647 return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_AKA; 648 case WifiEnterpriseConfig.Eap.AKA_PRIME: 649 return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_AKA_PRIME; 650 default: 651 return WifiMetricsProto.RouterFingerPrint.TYPE_EAP_UNKNOWN; 652 } 653 } getAuthPhase2MethodProto(int phase2Method)654 private int getAuthPhase2MethodProto(int phase2Method) { 655 switch (phase2Method) { 656 case WifiEnterpriseConfig.Phase2.PAP: 657 return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_PAP; 658 case WifiEnterpriseConfig.Phase2.MSCHAP: 659 return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_MSCHAP; 660 case WifiEnterpriseConfig.Phase2.MSCHAPV2: 661 return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_MSCHAPV2; 662 case WifiEnterpriseConfig.Phase2.GTC: 663 return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_GTC; 664 case WifiEnterpriseConfig.Phase2.SIM: 665 return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_SIM; 666 case WifiEnterpriseConfig.Phase2.AKA: 667 return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_AKA; 668 case WifiEnterpriseConfig.Phase2.AKA_PRIME: 669 return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_AKA_PRIME; 670 default: 671 return WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_NONE; 672 } 673 } 674 getOcspTypeProto(int ocspType)675 private int getOcspTypeProto(int ocspType) { 676 switch (ocspType) { 677 case WifiEnterpriseConfig.OCSP_NONE: 678 return WifiMetricsProto.RouterFingerPrint.TYPE_OCSP_NONE; 679 case WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS: 680 return WifiMetricsProto.RouterFingerPrint.TYPE_OCSP_REQUEST_CERT_STATUS; 681 case WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS: 682 return WifiMetricsProto.RouterFingerPrint.TYPE_OCSP_REQUIRE_CERT_STATUS; 683 case WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS: 684 return WifiMetricsProto.RouterFingerPrint 685 .TYPE_OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS; 686 default: 687 return WifiMetricsProto.RouterFingerPrint.TYPE_OCSP_NONE; 688 } 689 } 690 691 class BssidBlocklistStats { 692 public IntCounter networkSelectionFilteredBssidCount = new IntCounter(); 693 public int numHighMovementConnectionSkipped = 0; 694 public int numHighMovementConnectionStarted = 0; 695 toProto()696 public WifiMetricsProto.BssidBlocklistStats toProto() { 697 WifiMetricsProto.BssidBlocklistStats proto = new WifiMetricsProto.BssidBlocklistStats(); 698 proto.networkSelectionFilteredBssidCount = networkSelectionFilteredBssidCount.toProto(); 699 proto.highMovementMultipleScansFeatureEnabled = mContext.getResources().getBoolean( 700 R.bool.config_wifiHighMovementNetworkSelectionOptimizationEnabled); 701 proto.numHighMovementConnectionSkipped = numHighMovementConnectionSkipped; 702 proto.numHighMovementConnectionStarted = numHighMovementConnectionStarted; 703 return proto; 704 } 705 706 @Override toString()707 public String toString() { 708 StringBuilder sb = new StringBuilder(); 709 sb.append("networkSelectionFilteredBssidCount=" + networkSelectionFilteredBssidCount); 710 sb.append(", highMovementMultipleScansFeatureEnabled=" 711 + mContext.getResources().getBoolean( 712 R.bool.config_wifiHighMovementNetworkSelectionOptimizationEnabled)); 713 sb.append(", numHighMovementConnectionSkipped=" + numHighMovementConnectionSkipped); 714 sb.append(", numHighMovementConnectionStarted=" + numHighMovementConnectionStarted); 715 return sb.toString(); 716 } 717 } 718 719 class ConnectionDurationStats { 720 private int mConnectionDurationCellularDataOffMs; 721 private int mConnectionDurationSufficientThroughputMs; 722 private int mConnectionDurationInSufficientThroughputMs; 723 toProto()724 public WifiMetricsProto.ConnectionDurationStats toProto() { 725 WifiMetricsProto.ConnectionDurationStats proto = 726 new WifiMetricsProto.ConnectionDurationStats(); 727 proto.totalTimeSufficientThroughputMs = mConnectionDurationSufficientThroughputMs; 728 proto.totalTimeInsufficientThroughputMs = mConnectionDurationInSufficientThroughputMs; 729 proto.totalTimeCellularDataOffMs = mConnectionDurationCellularDataOffMs; 730 return proto; 731 } clear()732 public void clear() { 733 mConnectionDurationCellularDataOffMs = 0; 734 mConnectionDurationSufficientThroughputMs = 0; 735 mConnectionDurationInSufficientThroughputMs = 0; 736 } incrementDurationCount(int timeDeltaLastTwoPollsMs, boolean isThroughputSufficient, boolean isCellularDataAvailable)737 public void incrementDurationCount(int timeDeltaLastTwoPollsMs, 738 boolean isThroughputSufficient, boolean isCellularDataAvailable) { 739 if (!isCellularDataAvailable) { 740 mConnectionDurationCellularDataOffMs += timeDeltaLastTwoPollsMs; 741 } else { 742 if (isThroughputSufficient) { 743 mConnectionDurationSufficientThroughputMs += timeDeltaLastTwoPollsMs; 744 } else { 745 mConnectionDurationInSufficientThroughputMs += timeDeltaLastTwoPollsMs; 746 } 747 } 748 } 749 @Override toString()750 public String toString() { 751 StringBuilder sb = new StringBuilder(); 752 sb.append("connectionDurationSufficientThroughputMs=") 753 .append(mConnectionDurationSufficientThroughputMs) 754 .append(", connectionDurationInSufficientThroughputMs=") 755 .append(mConnectionDurationInSufficientThroughputMs) 756 .append(", connectionDurationCellularDataOffMs=") 757 .append(mConnectionDurationCellularDataOffMs); 758 return sb.toString(); 759 } 760 } 761 762 class WifiStatusBuilder { 763 private int mNetworkId = WifiConfiguration.INVALID_NETWORK_ID; 764 private boolean mConnected; 765 private boolean mValidated; 766 private int mRssi; 767 private int mEstimatedTxKbps; 768 private int mEstimatedRxKbps; 769 private boolean mIsStuckDueToUserChoice; 770 setNetworkId(int networkId)771 public void setNetworkId(int networkId) { 772 mNetworkId = networkId; 773 } 774 getNetworkId()775 public int getNetworkId() { 776 return mNetworkId; 777 } 778 setConnected(boolean connected)779 public void setConnected(boolean connected) { 780 mConnected = connected; 781 } 782 setValidated(boolean validated)783 public void setValidated(boolean validated) { 784 mValidated = validated; 785 } 786 setRssi(int rssi)787 public void setRssi(int rssi) { 788 mRssi = rssi; 789 } 790 setEstimatedTxKbps(int estimatedTxKbps)791 public void setEstimatedTxKbps(int estimatedTxKbps) { 792 mEstimatedTxKbps = estimatedTxKbps; 793 } 794 setEstimatedRxKbps(int estimatedRxKbps)795 public void setEstimatedRxKbps(int estimatedRxKbps) { 796 mEstimatedRxKbps = estimatedRxKbps; 797 } 798 setUserChoice(boolean userChoice)799 public void setUserChoice(boolean userChoice) { 800 mIsStuckDueToUserChoice = userChoice; 801 } 802 toProto()803 public WifiStatus toProto() { 804 WifiStatus result = new WifiStatus(); 805 result.isConnected = mConnected; 806 result.isValidated = mValidated; 807 result.lastRssi = mRssi; 808 result.estimatedTxKbps = mEstimatedTxKbps; 809 result.estimatedRxKbps = mEstimatedRxKbps; 810 result.isStuckDueToUserConnectChoice = mIsStuckDueToUserChoice; 811 return result; 812 } 813 } 814 convertToNetworkDisableReason( WifiConfiguration config, Set<Integer> bssidBlocklistReasons)815 private NetworkDisableReason convertToNetworkDisableReason( 816 WifiConfiguration config, Set<Integer> bssidBlocklistReasons) { 817 NetworkSelectionStatus status = config.getNetworkSelectionStatus(); 818 NetworkDisableReason result = new NetworkDisableReason(); 819 if (config.allowAutojoin) { 820 if (!status.isNetworkEnabled()) { 821 result.disableReason = 822 MetricsUtils.convertNetworkSelectionDisableReasonToWifiProtoEnum( 823 status.getNetworkSelectionDisableReason()); 824 if (status.isNetworkPermanentlyDisabled()) { 825 result.configPermanentlyDisabled = true; 826 } else { 827 result.configTemporarilyDisabled = true; 828 } 829 } 830 } else { 831 result.disableReason = NetworkDisableReason.REASON_AUTO_JOIN_DISABLED; 832 result.configPermanentlyDisabled = true; 833 } 834 835 int[] convertedBssidBlockReasons = bssidBlocklistReasons.stream() 836 .mapToInt(i -> MetricsUtils.convertBssidBlocklistReasonToWifiProtoEnum(i)) 837 .toArray(); 838 if (convertedBssidBlockReasons.length > 0) { 839 result.bssidDisableReasons = convertedBssidBlockReasons; 840 } 841 return result; 842 } 843 844 class UserActionEventWithTime { 845 private UserActionEvent mUserActionEvent; 846 private long mWallClockTimeMs = 0; // wall clock time for debugging only 847 UserActionEventWithTime(int eventType, TargetNetworkInfo targetNetworkInfo)848 UserActionEventWithTime(int eventType, TargetNetworkInfo targetNetworkInfo) { 849 mUserActionEvent = new UserActionEvent(); 850 mUserActionEvent.eventType = eventType; 851 mUserActionEvent.startTimeMillis = mClock.getElapsedSinceBootMillis(); 852 mWallClockTimeMs = mClock.getWallClockMillis(); 853 mUserActionEvent.targetNetworkInfo = targetNetworkInfo; 854 mUserActionEvent.wifiStatus = mWifiStatusBuilder.toProto(); 855 } 856 UserActionEventWithTime(int eventType, int targetNetId)857 UserActionEventWithTime(int eventType, int targetNetId) { 858 this(eventType, null); 859 if (targetNetId >= 0) { 860 WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(targetNetId); 861 if (config != null) { 862 TargetNetworkInfo networkInfo = new TargetNetworkInfo(); 863 networkInfo.isEphemeral = config.isEphemeral(); 864 networkInfo.isPasspoint = config.isPasspoint(); 865 mUserActionEvent.targetNetworkInfo = networkInfo; 866 mUserActionEvent.networkDisableReason = convertToNetworkDisableReason( 867 config, mBssidBlocklistMonitor.getFailureReasonsForSsid(config.SSID)); 868 } 869 } 870 } 871 toString()872 public String toString() { 873 StringBuilder sb = new StringBuilder(); 874 Calendar c = Calendar.getInstance(); 875 c.setTimeInMillis(mWallClockTimeMs); 876 sb.append(String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)); 877 String eventType = "UNKNOWN"; 878 switch (mUserActionEvent.eventType) { 879 case UserActionEvent.EVENT_FORGET_WIFI: 880 eventType = "EVENT_FORGET_WIFI"; 881 break; 882 case UserActionEvent.EVENT_DISCONNECT_WIFI: 883 eventType = "EVENT_DISCONNECT_WIFI"; 884 break; 885 case UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_METERED: 886 eventType = "EVENT_CONFIGURE_METERED_STATUS_METERED"; 887 break; 888 case UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_UNMETERED: 889 eventType = "EVENT_CONFIGURE_METERED_STATUS_UNMETERED"; 890 break; 891 case UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_AUTO: 892 eventType = "EVENT_CONFIGURE_METERED_STATUS_AUTO"; 893 break; 894 case UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_ON: 895 eventType = "EVENT_CONFIGURE_MAC_RANDOMIZATION_ON"; 896 break; 897 case UserActionEvent.EVENT_CONFIGURE_MAC_RANDOMIZATION_OFF: 898 eventType = "EVENT_CONFIGURE_MAC_RANDOMIZATION_OFF"; 899 break; 900 case UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_ON: 901 eventType = "EVENT_CONFIGURE_AUTO_CONNECT_ON"; 902 break; 903 case UserActionEvent.EVENT_CONFIGURE_AUTO_CONNECT_OFF: 904 eventType = "EVENT_CONFIGURE_AUTO_CONNECT_OFF"; 905 break; 906 case UserActionEvent.EVENT_TOGGLE_WIFI_ON: 907 eventType = "EVENT_TOGGLE_WIFI_ON"; 908 break; 909 case UserActionEvent.EVENT_TOGGLE_WIFI_OFF: 910 eventType = "EVENT_TOGGLE_WIFI_OFF"; 911 break; 912 case UserActionEvent.EVENT_MANUAL_CONNECT: 913 eventType = "EVENT_MANUAL_CONNECT"; 914 break; 915 case UserActionEvent.EVENT_ADD_OR_UPDATE_NETWORK: 916 eventType = "EVENT_ADD_OR_UPDATE_NETWORK"; 917 break; 918 } 919 sb.append(" eventType=").append(eventType); 920 sb.append(" startTimeMillis=").append(mUserActionEvent.startTimeMillis); 921 TargetNetworkInfo networkInfo = mUserActionEvent.targetNetworkInfo; 922 if (networkInfo != null) { 923 sb.append(" isEphemeral=").append(networkInfo.isEphemeral); 924 sb.append(" isPasspoint=").append(networkInfo.isPasspoint); 925 } 926 WifiStatus wifiStatus = mUserActionEvent.wifiStatus; 927 if (wifiStatus != null) { 928 sb.append("\nWifiStatus: isConnected=").append(wifiStatus.isConnected); 929 sb.append(" isValidated=").append(wifiStatus.isValidated); 930 sb.append(" lastRssi=").append(wifiStatus.lastRssi); 931 sb.append(" estimatedTxKbps=").append(wifiStatus.estimatedTxKbps); 932 sb.append(" estimatedRxKbps=").append(wifiStatus.estimatedRxKbps); 933 sb.append(" isStuckDueToUserConnectChoice=") 934 .append(wifiStatus.isStuckDueToUserConnectChoice); 935 } 936 NetworkDisableReason disableReason = mUserActionEvent.networkDisableReason; 937 if (disableReason != null) { 938 sb.append("\nNetworkDisableReason: DisableReason=") 939 .append(disableReason.disableReason); 940 sb.append(" configTemporarilyDisabled=") 941 .append(disableReason.configTemporarilyDisabled); 942 sb.append(" configPermanentlyDisabled=") 943 .append(disableReason.configPermanentlyDisabled); 944 sb.append(" bssidDisableReasons=") 945 .append(Arrays.toString(disableReason.bssidDisableReasons)); 946 } 947 return sb.toString(); 948 } 949 toProto()950 public UserActionEvent toProto() { 951 return mUserActionEvent; 952 } 953 } 954 955 /** 956 * Log event, tracking the start time, end time and result of a wireless connection attempt. 957 */ 958 class ConnectionEvent { 959 WifiMetricsProto.ConnectionEvent mConnectionEvent; 960 //<TODO> Move these constants into a wifi.proto Enum, and create a new Failure Type field 961 //covering more than just l2 failures. see b/27652362 962 /** 963 * Failure codes, used for the 'level_2_failure_code' Connection event field (covers a lot 964 * more failures than just l2 though, since the proto does not have a place to log 965 * framework failures) 966 */ 967 // Failure is unknown 968 public static final int FAILURE_UNKNOWN = 0; 969 // NONE 970 public static final int FAILURE_NONE = 1; 971 // ASSOCIATION_REJECTION_EVENT 972 public static final int FAILURE_ASSOCIATION_REJECTION = 2; 973 // AUTHENTICATION_FAILURE_EVENT 974 public static final int FAILURE_AUTHENTICATION_FAILURE = 3; 975 // SSID_TEMP_DISABLED (Also Auth failure) 976 public static final int FAILURE_SSID_TEMP_DISABLED = 4; 977 // reconnect() or reassociate() call to WifiNative failed 978 public static final int FAILURE_CONNECT_NETWORK_FAILED = 5; 979 // NETWORK_DISCONNECTION_EVENT 980 public static final int FAILURE_NETWORK_DISCONNECTION = 6; 981 // NEW_CONNECTION_ATTEMPT before previous finished 982 public static final int FAILURE_NEW_CONNECTION_ATTEMPT = 7; 983 // New connection attempt to the same network & bssid 984 public static final int FAILURE_REDUNDANT_CONNECTION_ATTEMPT = 8; 985 // Roam Watchdog timer triggered (Roaming timed out) 986 public static final int FAILURE_ROAM_TIMEOUT = 9; 987 // DHCP failure 988 public static final int FAILURE_DHCP = 10; 989 // ASSOCIATION_TIMED_OUT 990 public static final int FAILURE_ASSOCIATION_TIMED_OUT = 11; 991 992 RouterFingerPrint mRouterFingerPrint; 993 private long mRealStartTime; 994 private long mRealEndTime; 995 private String mConfigSsid; 996 private String mConfigBssid; 997 private int mWifiState; 998 private boolean mScreenOn; 999 ConnectionEvent()1000 private ConnectionEvent() { 1001 mConnectionEvent = new WifiMetricsProto.ConnectionEvent(); 1002 mRealEndTime = 0; 1003 mRealStartTime = 0; 1004 mRouterFingerPrint = new RouterFingerPrint(); 1005 mConnectionEvent.routerFingerprint = mRouterFingerPrint.mRouterFingerPrintProto; 1006 mConfigSsid = "<NULL>"; 1007 mConfigBssid = "<NULL>"; 1008 mWifiState = WifiMetricsProto.WifiLog.WIFI_UNKNOWN; 1009 mScreenOn = false; 1010 } 1011 toString()1012 public String toString() { 1013 StringBuilder sb = new StringBuilder(); 1014 sb.append("startTime="); 1015 Calendar c = Calendar.getInstance(); 1016 synchronized (mLock) { 1017 c.setTimeInMillis(mConnectionEvent.startTimeMillis); 1018 sb.append(mConnectionEvent.startTimeMillis == 0 ? " <null>" : 1019 String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)); 1020 sb.append(", SSID="); 1021 sb.append(mConfigSsid); 1022 sb.append(", BSSID="); 1023 sb.append(mConfigBssid); 1024 sb.append(", durationMillis="); 1025 sb.append(mConnectionEvent.durationTakenToConnectMillis); 1026 sb.append(", roamType="); 1027 switch(mConnectionEvent.roamType) { 1028 case 1: 1029 sb.append("ROAM_NONE"); 1030 break; 1031 case 2: 1032 sb.append("ROAM_DBDC"); 1033 break; 1034 case 3: 1035 sb.append("ROAM_ENTERPRISE"); 1036 break; 1037 case 4: 1038 sb.append("ROAM_USER_SELECTED"); 1039 break; 1040 case 5: 1041 sb.append("ROAM_UNRELATED"); 1042 break; 1043 default: 1044 sb.append("ROAM_UNKNOWN"); 1045 } 1046 sb.append(", connectionResult="); 1047 sb.append(mConnectionEvent.connectionResult); 1048 sb.append(", level2FailureCode="); 1049 switch(mConnectionEvent.level2FailureCode) { 1050 case FAILURE_NONE: 1051 sb.append("NONE"); 1052 break; 1053 case FAILURE_ASSOCIATION_REJECTION: 1054 sb.append("ASSOCIATION_REJECTION"); 1055 break; 1056 case FAILURE_AUTHENTICATION_FAILURE: 1057 sb.append("AUTHENTICATION_FAILURE"); 1058 break; 1059 case FAILURE_SSID_TEMP_DISABLED: 1060 sb.append("SSID_TEMP_DISABLED"); 1061 break; 1062 case FAILURE_CONNECT_NETWORK_FAILED: 1063 sb.append("CONNECT_NETWORK_FAILED"); 1064 break; 1065 case FAILURE_NETWORK_DISCONNECTION: 1066 sb.append("NETWORK_DISCONNECTION"); 1067 break; 1068 case FAILURE_NEW_CONNECTION_ATTEMPT: 1069 sb.append("NEW_CONNECTION_ATTEMPT"); 1070 break; 1071 case FAILURE_REDUNDANT_CONNECTION_ATTEMPT: 1072 sb.append("REDUNDANT_CONNECTION_ATTEMPT"); 1073 break; 1074 case FAILURE_ROAM_TIMEOUT: 1075 sb.append("ROAM_TIMEOUT"); 1076 break; 1077 case FAILURE_DHCP: 1078 sb.append("DHCP"); 1079 break; 1080 case FAILURE_ASSOCIATION_TIMED_OUT: 1081 sb.append("ASSOCIATION_TIMED_OUT"); 1082 break; 1083 default: 1084 sb.append("UNKNOWN"); 1085 break; 1086 } 1087 sb.append(", connectivityLevelFailureCode="); 1088 switch(mConnectionEvent.connectivityLevelFailureCode) { 1089 case WifiMetricsProto.ConnectionEvent.HLF_NONE: 1090 sb.append("NONE"); 1091 break; 1092 case WifiMetricsProto.ConnectionEvent.HLF_DHCP: 1093 sb.append("DHCP"); 1094 break; 1095 case WifiMetricsProto.ConnectionEvent.HLF_NO_INTERNET: 1096 sb.append("NO_INTERNET"); 1097 break; 1098 case WifiMetricsProto.ConnectionEvent.HLF_UNWANTED: 1099 sb.append("UNWANTED"); 1100 break; 1101 default: 1102 sb.append("UNKNOWN"); 1103 break; 1104 } 1105 sb.append(", signalStrength="); 1106 sb.append(mConnectionEvent.signalStrength); 1107 sb.append(", wifiState="); 1108 switch(mWifiState) { 1109 case WifiMetricsProto.WifiLog.WIFI_DISABLED: 1110 sb.append("WIFI_DISABLED"); 1111 break; 1112 case WifiMetricsProto.WifiLog.WIFI_DISCONNECTED: 1113 sb.append("WIFI_DISCONNECTED"); 1114 break; 1115 case WifiMetricsProto.WifiLog.WIFI_ASSOCIATED: 1116 sb.append("WIFI_ASSOCIATED"); 1117 break; 1118 default: 1119 sb.append("WIFI_UNKNOWN"); 1120 break; 1121 } 1122 sb.append(", screenOn="); 1123 sb.append(mScreenOn); 1124 sb.append(", mRouterFingerprint="); 1125 sb.append(mRouterFingerPrint.toString()); 1126 sb.append(", useRandomizedMac="); 1127 sb.append(mConnectionEvent.useRandomizedMac); 1128 sb.append(", useAggressiveMac=" + mConnectionEvent.useAggressiveMac); 1129 sb.append(", connectionNominator="); 1130 switch (mConnectionEvent.connectionNominator) { 1131 case WifiMetricsProto.ConnectionEvent.NOMINATOR_UNKNOWN: 1132 sb.append("NOMINATOR_UNKNOWN"); 1133 break; 1134 case WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL: 1135 sb.append("NOMINATOR_MANUAL"); 1136 break; 1137 case WifiMetricsProto.ConnectionEvent.NOMINATOR_SAVED: 1138 sb.append("NOMINATOR_SAVED"); 1139 break; 1140 case WifiMetricsProto.ConnectionEvent.NOMINATOR_SUGGESTION: 1141 sb.append("NOMINATOR_SUGGESTION"); 1142 break; 1143 case WifiMetricsProto.ConnectionEvent.NOMINATOR_PASSPOINT: 1144 sb.append("NOMINATOR_PASSPOINT"); 1145 break; 1146 case WifiMetricsProto.ConnectionEvent.NOMINATOR_CARRIER: 1147 sb.append("NOMINATOR_CARRIER"); 1148 break; 1149 case WifiMetricsProto.ConnectionEvent.NOMINATOR_EXTERNAL_SCORED: 1150 sb.append("NOMINATOR_EXTERNAL_SCORED"); 1151 break; 1152 case WifiMetricsProto.ConnectionEvent.NOMINATOR_SPECIFIER: 1153 sb.append("NOMINATOR_SPECIFIER"); 1154 break; 1155 case WifiMetricsProto.ConnectionEvent.NOMINATOR_SAVED_USER_CONNECT_CHOICE: 1156 sb.append("NOMINATOR_SAVED_USER_CONNECT_CHOICE"); 1157 break; 1158 case WifiMetricsProto.ConnectionEvent.NOMINATOR_OPEN_NETWORK_AVAILABLE: 1159 sb.append("NOMINATOR_OPEN_NETWORK_AVAILABLE"); 1160 break; 1161 default: 1162 sb.append(String.format("UnrecognizedNominator(%d)", 1163 mConnectionEvent.connectionNominator)); 1164 } 1165 sb.append(", networkSelectorExperimentId="); 1166 sb.append(mConnectionEvent.networkSelectorExperimentId); 1167 sb.append(", numBssidInBlocklist=" + mConnectionEvent.numBssidInBlocklist); 1168 sb.append(", level2FailureReason="); 1169 switch(mConnectionEvent.level2FailureReason) { 1170 case WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_NONE: 1171 sb.append("AUTH_FAILURE_NONE"); 1172 break; 1173 case WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_TIMEOUT: 1174 sb.append("AUTH_FAILURE_TIMEOUT"); 1175 break; 1176 case WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_WRONG_PSWD: 1177 sb.append("AUTH_FAILURE_WRONG_PSWD"); 1178 break; 1179 case WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_EAP_FAILURE: 1180 sb.append("AUTH_FAILURE_EAP_FAILURE"); 1181 break; 1182 default: 1183 sb.append("FAILURE_REASON_UNKNOWN"); 1184 break; 1185 } 1186 sb.append(", networkType="); 1187 switch(mConnectionEvent.networkType) { 1188 case WifiMetricsProto.ConnectionEvent.TYPE_UNKNOWN: 1189 sb.append("TYPE_UNKNOWN"); 1190 break; 1191 case WifiMetricsProto.ConnectionEvent.TYPE_WPA2: 1192 sb.append("TYPE_WPA2"); 1193 break; 1194 case WifiMetricsProto.ConnectionEvent.TYPE_WPA3: 1195 sb.append("TYPE_WPA3"); 1196 break; 1197 case WifiMetricsProto.ConnectionEvent.TYPE_PASSPOINT: 1198 sb.append("TYPE_PASSPOINT"); 1199 break; 1200 case WifiMetricsProto.ConnectionEvent.TYPE_EAP: 1201 sb.append("TYPE_EAP"); 1202 break; 1203 case WifiMetricsProto.ConnectionEvent.TYPE_OWE: 1204 sb.append("TYPE_OWE"); 1205 break; 1206 case WifiMetricsProto.ConnectionEvent.TYPE_OPEN: 1207 sb.append("TYPE_OPEN"); 1208 break; 1209 case WifiMetricsProto.ConnectionEvent.TYPE_WAPI: 1210 sb.append("TYPE_WAPI"); 1211 break; 1212 } 1213 sb.append(", networkCreator="); 1214 switch (mConnectionEvent.networkCreator) { 1215 case WifiMetricsProto.ConnectionEvent.CREATOR_UNKNOWN: 1216 sb.append("CREATOR_UNKNOWN"); 1217 break; 1218 case WifiMetricsProto.ConnectionEvent.CREATOR_USER: 1219 sb.append("CREATOR_USER"); 1220 break; 1221 case WifiMetricsProto.ConnectionEvent.CREATOR_CARRIER: 1222 sb.append("CREATOR_CARRIER"); 1223 break; 1224 } 1225 sb.append(", numConsecutiveConnectionFailure=" 1226 + mConnectionEvent.numConsecutiveConnectionFailure); 1227 sb.append(", isOsuProvisioned=" + mConnectionEvent.isOsuProvisioned); 1228 } 1229 return sb.toString(); 1230 } 1231 } 1232 1233 class WifiOffMetrics { 1234 public int numWifiOff = 0; 1235 public int numWifiOffDeferring = 0; 1236 public int numWifiOffDeferringTimeout = 0; 1237 public final IntCounter wifiOffDeferringTimeHistogram = new IntCounter(); 1238 toProto()1239 public WifiMetricsProto.WifiOffMetrics toProto() { 1240 WifiMetricsProto.WifiOffMetrics proto = 1241 new WifiMetricsProto.WifiOffMetrics(); 1242 proto.numWifiOff = numWifiOff; 1243 proto.numWifiOffDeferring = numWifiOffDeferring; 1244 proto.numWifiOffDeferringTimeout = numWifiOffDeferringTimeout; 1245 proto.wifiOffDeferringTimeHistogram = wifiOffDeferringTimeHistogram.toProto(); 1246 return proto; 1247 } 1248 clear()1249 public void clear() { 1250 numWifiOff = 0; 1251 numWifiOffDeferring = 0; 1252 numWifiOffDeferringTimeout = 0; 1253 wifiOffDeferringTimeHistogram.clear(); 1254 } 1255 1256 @Override toString()1257 public String toString() { 1258 StringBuilder sb = new StringBuilder(); 1259 sb.append("numWifiOff=") 1260 .append(numWifiOff) 1261 .append(", numWifiOffDeferring=") 1262 .append(numWifiOffDeferring) 1263 .append(", numWifiOffDeferringTimeout=") 1264 .append(numWifiOffDeferringTimeout) 1265 .append(", wifiOffDeferringTimeHistogram=") 1266 .append(wifiOffDeferringTimeHistogram); 1267 return sb.toString(); 1268 } 1269 } 1270 1271 class SoftApConfigLimitationMetrics { 1272 // Collect the number of softap security setting reset to default during the restore 1273 public int numSecurityTypeResetToDefault = 0; 1274 // Collect the number of softap max client setting reset to default during the restore 1275 public int numMaxClientSettingResetToDefault = 0; 1276 // Collect the number of softap client control setting reset to default during the restore 1277 public int numClientControlByUserResetToDefault = 0; 1278 // Collect the max client setting when reach it cause client is blocked 1279 public final IntCounter maxClientSettingWhenReachHistogram = new IntCounter(); 1280 toProto()1281 public WifiMetricsProto.SoftApConfigLimitationMetrics toProto() { 1282 WifiMetricsProto.SoftApConfigLimitationMetrics proto = 1283 new WifiMetricsProto.SoftApConfigLimitationMetrics(); 1284 proto.numSecurityTypeResetToDefault = numSecurityTypeResetToDefault; 1285 proto.numMaxClientSettingResetToDefault = numMaxClientSettingResetToDefault; 1286 proto.numClientControlByUserResetToDefault = numClientControlByUserResetToDefault; 1287 proto.maxClientSettingWhenReachHistogram = maxClientSettingWhenReachHistogram.toProto(); 1288 return proto; 1289 } 1290 clear()1291 public void clear() { 1292 numSecurityTypeResetToDefault = 0; 1293 numMaxClientSettingResetToDefault = 0; 1294 numClientControlByUserResetToDefault = 0; 1295 maxClientSettingWhenReachHistogram.clear(); 1296 } 1297 1298 @Override toString()1299 public String toString() { 1300 StringBuilder sb = new StringBuilder(); 1301 sb.append("numSecurityTypeResetToDefault=") 1302 .append(numSecurityTypeResetToDefault) 1303 .append(", numMaxClientSettingResetToDefault=") 1304 .append(numMaxClientSettingResetToDefault) 1305 .append(", numClientControlByUserResetToDefault=") 1306 .append(numClientControlByUserResetToDefault) 1307 .append(", maxClientSettingWhenReachHistogram=") 1308 .append(maxClientSettingWhenReachHistogram); 1309 return sb.toString(); 1310 } 1311 } 1312 1313 class CarrierWifiMetrics { 1314 public int numConnectionSuccess = 0; 1315 public int numConnectionAuthFailure = 0; 1316 public int numConnectionNonAuthFailure = 0; 1317 toProto()1318 public WifiMetricsProto.CarrierWifiMetrics toProto() { 1319 WifiMetricsProto.CarrierWifiMetrics proto = 1320 new WifiMetricsProto.CarrierWifiMetrics(); 1321 proto.numConnectionSuccess = numConnectionSuccess; 1322 proto.numConnectionAuthFailure = numConnectionAuthFailure; 1323 proto.numConnectionNonAuthFailure = numConnectionNonAuthFailure; 1324 return proto; 1325 } 1326 clear()1327 public void clear() { 1328 numConnectionSuccess = 0; 1329 numConnectionAuthFailure = 0; 1330 numConnectionNonAuthFailure = 0; 1331 } 1332 1333 @Override toString()1334 public String toString() { 1335 StringBuilder sb = new StringBuilder(); 1336 sb.append("numConnectionSuccess=") 1337 .append(numConnectionSuccess) 1338 .append(", numConnectionAuthFailure=") 1339 .append(numConnectionAuthFailure) 1340 .append(", numConnectionNonAuthFailure") 1341 .append(numConnectionNonAuthFailure); 1342 return sb.toString(); 1343 } 1344 } 1345 WifiMetrics(Context context, FrameworkFacade facade, Clock clock, Looper looper, WifiAwareMetrics awareMetrics, RttMetrics rttMetrics, WifiPowerMetrics wifiPowerMetrics, WifiP2pMetrics wifiP2pMetrics, DppMetrics dppMetrics)1346 public WifiMetrics(Context context, FrameworkFacade facade, Clock clock, Looper looper, 1347 WifiAwareMetrics awareMetrics, RttMetrics rttMetrics, 1348 WifiPowerMetrics wifiPowerMetrics, WifiP2pMetrics wifiP2pMetrics, 1349 DppMetrics dppMetrics) { 1350 mContext = context; 1351 mFacade = facade; 1352 mClock = clock; 1353 mCurrentConnectionEvent = null; 1354 mScreenOn = true; 1355 mWifiState = WifiMetricsProto.WifiLog.WIFI_DISABLED; 1356 mRecordStartTimeSec = mClock.getElapsedSinceBootMillis() / 1000; 1357 mWifiAwareMetrics = awareMetrics; 1358 mRttMetrics = rttMetrics; 1359 mWifiPowerMetrics = wifiPowerMetrics; 1360 mWifiP2pMetrics = wifiP2pMetrics; 1361 mDppMetrics = dppMetrics; 1362 mHandler = new Handler(looper) { 1363 public void handleMessage(Message msg) { 1364 synchronized (mLock) { 1365 processMessage(msg); 1366 } 1367 } 1368 }; 1369 1370 mCurrentDeviceMobilityState = WifiManager.DEVICE_MOBILITY_STATE_UNKNOWN; 1371 DeviceMobilityStatePnoScanStats unknownStateStats = 1372 getOrCreateDeviceMobilityStatePnoScanStats(mCurrentDeviceMobilityState); 1373 unknownStateStats.numTimesEnteredState++; 1374 mCurrentDeviceMobilityStateStartMs = mClock.getElapsedSinceBootMillis(); 1375 mCurrentDeviceMobilityStatePnoScanStartMs = -1; 1376 mOnWifiUsabilityListeners = 1377 new ExternalCallbackTracker<IOnWifiUsabilityStatsListener>(mHandler); 1378 } 1379 1380 /** Sets internal ScoringParams member */ setScoringParams(ScoringParams scoringParams)1381 public void setScoringParams(ScoringParams scoringParams) { 1382 mScoringParams = scoringParams; 1383 } 1384 1385 /** Sets internal WifiConfigManager member */ setWifiConfigManager(WifiConfigManager wifiConfigManager)1386 public void setWifiConfigManager(WifiConfigManager wifiConfigManager) { 1387 mWifiConfigManager = wifiConfigManager; 1388 } 1389 1390 /** Sets internal WifiNetworkSelector member */ setWifiNetworkSelector(WifiNetworkSelector wifiNetworkSelector)1391 public void setWifiNetworkSelector(WifiNetworkSelector wifiNetworkSelector) { 1392 mWifiNetworkSelector = wifiNetworkSelector; 1393 } 1394 1395 /** Sets internal PasspointManager member */ setPasspointManager(PasspointManager passpointManager)1396 public void setPasspointManager(PasspointManager passpointManager) { 1397 mPasspointManager = passpointManager; 1398 } 1399 1400 /** Sets internal WifiDataStall member */ setWifiDataStall(WifiDataStall wifiDataStall)1401 public void setWifiDataStall(WifiDataStall wifiDataStall) { 1402 mWifiDataStall = wifiDataStall; 1403 } 1404 1405 /** Sets internal BssidBlocklistMonitor member */ setBssidBlocklistMonitor(BssidBlocklistMonitor bssidBlocklistMonitor)1406 public void setBssidBlocklistMonitor(BssidBlocklistMonitor bssidBlocklistMonitor) { 1407 mBssidBlocklistMonitor = bssidBlocklistMonitor; 1408 } 1409 1410 /** Sets internal WifiHealthMonitor member */ setWifiHealthMonitor(WifiHealthMonitor wifiHealthMonitor)1411 public void setWifiHealthMonitor(WifiHealthMonitor wifiHealthMonitor) { 1412 mWifiHealthMonitor = wifiHealthMonitor; 1413 } 1414 1415 /** Sets internal WifiScoreCard member */ setWifiScoreCard(WifiScoreCard wifiScoreCard)1416 public void setWifiScoreCard(WifiScoreCard wifiScoreCard) { 1417 mWifiScoreCard = wifiScoreCard; 1418 } 1419 1420 /** 1421 * Increment cumulative counters for link layer stats. 1422 * @param newStats 1423 */ incrementWifiLinkLayerUsageStats(WifiLinkLayerStats newStats)1424 public void incrementWifiLinkLayerUsageStats(WifiLinkLayerStats newStats) { 1425 if (newStats == null) { 1426 return; 1427 } 1428 if (mLastLinkLayerStats == null) { 1429 mLastLinkLayerStats = newStats; 1430 return; 1431 } 1432 if (!newLinkLayerStatsIsValid(mLastLinkLayerStats, newStats)) { 1433 // This could mean the radio chip is reset or the data is incorrectly reported. 1434 // Don't increment any counts and discard the possibly corrupt |newStats| completely. 1435 mLastLinkLayerStats = null; 1436 return; 1437 } 1438 mWifiLinkLayerUsageStats.loggingDurationMs += 1439 (newStats.timeStampInMs - mLastLinkLayerStats.timeStampInMs); 1440 mWifiLinkLayerUsageStats.radioOnTimeMs += (newStats.on_time - mLastLinkLayerStats.on_time); 1441 mWifiLinkLayerUsageStats.radioTxTimeMs += (newStats.tx_time - mLastLinkLayerStats.tx_time); 1442 mWifiLinkLayerUsageStats.radioRxTimeMs += (newStats.rx_time - mLastLinkLayerStats.rx_time); 1443 mWifiLinkLayerUsageStats.radioScanTimeMs += 1444 (newStats.on_time_scan - mLastLinkLayerStats.on_time_scan); 1445 mWifiLinkLayerUsageStats.radioNanScanTimeMs += 1446 (newStats.on_time_nan_scan - mLastLinkLayerStats.on_time_nan_scan); 1447 mWifiLinkLayerUsageStats.radioBackgroundScanTimeMs += 1448 (newStats.on_time_background_scan - mLastLinkLayerStats.on_time_background_scan); 1449 mWifiLinkLayerUsageStats.radioRoamScanTimeMs += 1450 (newStats.on_time_roam_scan - mLastLinkLayerStats.on_time_roam_scan); 1451 mWifiLinkLayerUsageStats.radioPnoScanTimeMs += 1452 (newStats.on_time_pno_scan - mLastLinkLayerStats.on_time_pno_scan); 1453 mWifiLinkLayerUsageStats.radioHs20ScanTimeMs += 1454 (newStats.on_time_hs20_scan - mLastLinkLayerStats.on_time_hs20_scan); 1455 mLastLinkLayerStats = newStats; 1456 } 1457 newLinkLayerStatsIsValid(WifiLinkLayerStats oldStats, WifiLinkLayerStats newStats)1458 private boolean newLinkLayerStatsIsValid(WifiLinkLayerStats oldStats, 1459 WifiLinkLayerStats newStats) { 1460 if (newStats.on_time < oldStats.on_time 1461 || newStats.tx_time < oldStats.tx_time 1462 || newStats.rx_time < oldStats.rx_time 1463 || newStats.on_time_scan < oldStats.on_time_scan) { 1464 return false; 1465 } 1466 return true; 1467 } 1468 1469 /** 1470 * Increment total number of attempts to start a pno scan 1471 */ incrementPnoScanStartAttemptCount()1472 public void incrementPnoScanStartAttemptCount() { 1473 synchronized (mLock) { 1474 mPnoScanMetrics.numPnoScanAttempts++; 1475 } 1476 } 1477 1478 /** 1479 * Increment total number of attempts with pno scan failed 1480 */ incrementPnoScanFailedCount()1481 public void incrementPnoScanFailedCount() { 1482 synchronized (mLock) { 1483 mPnoScanMetrics.numPnoScanFailed++; 1484 } 1485 } 1486 1487 /** 1488 * Increment number of times pno scan found a result 1489 */ incrementPnoFoundNetworkEventCount()1490 public void incrementPnoFoundNetworkEventCount() { 1491 synchronized (mLock) { 1492 mPnoScanMetrics.numPnoFoundNetworkEvents++; 1493 } 1494 } 1495 1496 // Values used for indexing SystemStateEntries 1497 private static final int SCREEN_ON = 1; 1498 private static final int SCREEN_OFF = 0; 1499 1500 /** 1501 * Create a new connection event and check if the new one overlaps with previous one. 1502 * Call when wifi attempts to make a new network connection 1503 * If there is a current 'un-ended' connection event, it will be ended with UNKNOWN connectivity 1504 * failure code. 1505 * Gathers and sets the RouterFingerPrint data as well 1506 * 1507 * @param config WifiConfiguration of the config used for the current connection attempt 1508 * @param roamType Roam type that caused connection attempt, see WifiMetricsProto.WifiLog.ROAM_X 1509 * @return The duration in ms since the last unfinished connection attempt, 1510 * or 0 if there is no unfinished connection 1511 */ startConnectionEvent( WifiConfiguration config, String targetBSSID, int roamType)1512 public int startConnectionEvent( 1513 WifiConfiguration config, String targetBSSID, int roamType) { 1514 synchronized (mLock) { 1515 int overlapWithLastConnectionMs = 0; 1516 if (mCurrentConnectionEvent != null) { 1517 overlapWithLastConnectionMs = (int) (mClock.getElapsedSinceBootMillis() 1518 - mCurrentConnectionEvent.mRealStartTime); 1519 //Is this new Connection Event the same as the current one 1520 if (mCurrentConnectionEvent.mConfigSsid != null 1521 && mCurrentConnectionEvent.mConfigBssid != null 1522 && config != null 1523 && mCurrentConnectionEvent.mConfigSsid.equals(config.SSID) 1524 && (mCurrentConnectionEvent.mConfigBssid.equals("any") 1525 || mCurrentConnectionEvent.mConfigBssid.equals(targetBSSID))) { 1526 mCurrentConnectionEvent.mConfigBssid = targetBSSID; 1527 // End Connection Event due to new connection attempt to the same network 1528 endConnectionEvent(ConnectionEvent.FAILURE_REDUNDANT_CONNECTION_ATTEMPT, 1529 WifiMetricsProto.ConnectionEvent.HLF_NONE, 1530 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN); 1531 } else { 1532 // End Connection Event due to new connection attempt to different network 1533 endConnectionEvent(ConnectionEvent.FAILURE_NEW_CONNECTION_ATTEMPT, 1534 WifiMetricsProto.ConnectionEvent.HLF_NONE, 1535 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN); 1536 } 1537 } 1538 //If past maximum connection events, start removing the oldest 1539 while(mConnectionEventList.size() >= MAX_CONNECTION_EVENTS) { 1540 mConnectionEventList.remove(0); 1541 } 1542 mCurrentConnectionEvent = new ConnectionEvent(); 1543 mCurrentConnectionEvent.mConnectionEvent.startTimeMillis = 1544 mClock.getWallClockMillis(); 1545 mCurrentConnectionEvent.mConfigBssid = targetBSSID; 1546 mCurrentConnectionEvent.mConnectionEvent.roamType = roamType; 1547 mCurrentConnectionEvent.mConnectionEvent.networkSelectorExperimentId = 1548 mNetworkSelectorExperimentId; 1549 mCurrentConnectionEvent.mRouterFingerPrint.updateFromWifiConfiguration(config); 1550 mCurrentConnectionEvent.mConfigBssid = "any"; 1551 mCurrentConnectionEvent.mRealStartTime = mClock.getElapsedSinceBootMillis(); 1552 mCurrentConnectionEvent.mWifiState = mWifiState; 1553 mCurrentConnectionEvent.mScreenOn = mScreenOn; 1554 mConnectionEventList.add(mCurrentConnectionEvent); 1555 mScanResultRssiTimestampMillis = -1; 1556 if (config != null) { 1557 mCurrentConnectionEvent.mConnectionEvent.useRandomizedMac = 1558 config.macRandomizationSetting 1559 == WifiConfiguration.RANDOMIZATION_PERSISTENT; 1560 mCurrentConnectionEvent.mConnectionEvent.useAggressiveMac = 1561 mWifiConfigManager.shouldUseAggressiveRandomization(config); 1562 mCurrentConnectionEvent.mConnectionEvent.connectionNominator = 1563 mNetworkIdToNominatorId.get(config.networkId, 1564 WifiMetricsProto.ConnectionEvent.NOMINATOR_UNKNOWN); 1565 ScanResult candidate = config.getNetworkSelectionStatus().getCandidate(); 1566 if (candidate != null) { 1567 // Cache the RSSI of the candidate, as the connection event level is updated 1568 // from other sources (polls, bssid_associations) and delta requires the 1569 // scanResult rssi 1570 mScanResultRssi = candidate.level; 1571 mScanResultRssiTimestampMillis = mClock.getElapsedSinceBootMillis(); 1572 } 1573 mCurrentConnectionEvent.mConnectionEvent.numBssidInBlocklist = 1574 mBssidBlocklistMonitor.updateAndGetNumBlockedBssidsForSsid(config.SSID); 1575 mCurrentConnectionEvent.mConnectionEvent.networkType = 1576 WifiMetricsProto.ConnectionEvent.TYPE_UNKNOWN; 1577 mCurrentConnectionEvent.mConnectionEvent.isOsuProvisioned = false; 1578 if (config.isPasspoint()) { 1579 mCurrentConnectionEvent.mConnectionEvent.networkType = 1580 WifiMetricsProto.ConnectionEvent.TYPE_PASSPOINT; 1581 mCurrentConnectionEvent.mConnectionEvent.isOsuProvisioned = 1582 !TextUtils.isEmpty(config.updateIdentifier); 1583 } else if (WifiConfigurationUtil.isConfigForSaeNetwork(config)) { 1584 mCurrentConnectionEvent.mConnectionEvent.networkType = 1585 WifiMetricsProto.ConnectionEvent.TYPE_WPA3; 1586 } else if (WifiConfigurationUtil.isConfigForWapiPskNetwork(config)) { 1587 mCurrentConnectionEvent.mConnectionEvent.networkType = 1588 WifiMetricsProto.ConnectionEvent.TYPE_WAPI; 1589 } else if (WifiConfigurationUtil.isConfigForWapiCertNetwork(config)) { 1590 mCurrentConnectionEvent.mConnectionEvent.networkType = 1591 WifiMetricsProto.ConnectionEvent.TYPE_WAPI; 1592 } else if (WifiConfigurationUtil.isConfigForPskNetwork(config)) { 1593 mCurrentConnectionEvent.mConnectionEvent.networkType = 1594 WifiMetricsProto.ConnectionEvent.TYPE_WPA2; 1595 } else if (WifiConfigurationUtil.isConfigForEapNetwork(config)) { 1596 mCurrentConnectionEvent.mConnectionEvent.networkType = 1597 WifiMetricsProto.ConnectionEvent.TYPE_EAP; 1598 } else if (WifiConfigurationUtil.isConfigForOweNetwork(config)) { 1599 mCurrentConnectionEvent.mConnectionEvent.networkType = 1600 WifiMetricsProto.ConnectionEvent.TYPE_OWE; 1601 } else if (WifiConfigurationUtil.isConfigForOpenNetwork(config)) { 1602 mCurrentConnectionEvent.mConnectionEvent.networkType = 1603 WifiMetricsProto.ConnectionEvent.TYPE_OPEN; 1604 } 1605 1606 if (!config.fromWifiNetworkSuggestion) { 1607 mCurrentConnectionEvent.mConnectionEvent.networkCreator = 1608 WifiMetricsProto.ConnectionEvent.CREATOR_USER; 1609 } else if (config.carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) { 1610 mCurrentConnectionEvent.mConnectionEvent.networkCreator = 1611 WifiMetricsProto.ConnectionEvent.CREATOR_CARRIER; 1612 } else { 1613 mCurrentConnectionEvent.mConnectionEvent.networkCreator = 1614 WifiMetricsProto.ConnectionEvent.CREATOR_UNKNOWN; 1615 } 1616 1617 mCurrentConnectionEvent.mConnectionEvent.screenOn = mScreenOn; 1618 if (mCurrentConnectionEvent.mConfigSsid != null) { 1619 WifiScoreCard.NetworkConnectionStats recentStats = mWifiScoreCard.lookupNetwork( 1620 mCurrentConnectionEvent.mConfigSsid).getRecentStats(); 1621 mCurrentConnectionEvent.mConnectionEvent.numConsecutiveConnectionFailure = 1622 recentStats.getCount(WifiScoreCard.CNT_CONSECUTIVE_CONNECTION_FAILURE); 1623 } 1624 } 1625 return overlapWithLastConnectionMs; 1626 } 1627 } 1628 1629 /** 1630 * set the RoamType of the current ConnectionEvent (if any) 1631 */ setConnectionEventRoamType(int roamType)1632 public void setConnectionEventRoamType(int roamType) { 1633 synchronized (mLock) { 1634 if (mCurrentConnectionEvent != null) { 1635 mCurrentConnectionEvent.mConnectionEvent.roamType = roamType; 1636 } 1637 } 1638 } 1639 1640 /** 1641 * Set AP related metrics from ScanDetail 1642 */ setConnectionScanDetail(ScanDetail scanDetail)1643 public void setConnectionScanDetail(ScanDetail scanDetail) { 1644 synchronized (mLock) { 1645 if (mCurrentConnectionEvent != null && scanDetail != null) { 1646 NetworkDetail networkDetail = scanDetail.getNetworkDetail(); 1647 ScanResult scanResult = scanDetail.getScanResult(); 1648 //Ensure that we have a networkDetail, and that it corresponds to the currently 1649 //tracked connection attempt 1650 if (networkDetail != null && scanResult != null 1651 && mCurrentConnectionEvent.mConfigSsid != null 1652 && mCurrentConnectionEvent.mConfigSsid 1653 .equals("\"" + networkDetail.getSSID() + "\"")) { 1654 updateMetricsFromNetworkDetail(networkDetail); 1655 updateMetricsFromScanResult(scanResult); 1656 } 1657 } 1658 } 1659 } 1660 1661 /** 1662 * Set PMK cache status for a connection event 1663 */ setConnectionPmkCache(boolean isEnabled)1664 public void setConnectionPmkCache(boolean isEnabled) { 1665 synchronized (mLock) { 1666 if (mCurrentConnectionEvent != null) { 1667 mCurrentConnectionEvent.mRouterFingerPrint.setPmkCache(isEnabled); 1668 } 1669 } 1670 } 1671 1672 /** 1673 * Set the max link speed supported by current network 1674 */ setConnectionMaxSupportedLinkSpeedMbps(int maxSupportedTxLinkSpeedMbps, int maxSupportedRxLinkSpeedMbps)1675 public void setConnectionMaxSupportedLinkSpeedMbps(int maxSupportedTxLinkSpeedMbps, 1676 int maxSupportedRxLinkSpeedMbps) { 1677 synchronized (mLock) { 1678 if (mCurrentConnectionEvent != null) { 1679 mCurrentConnectionEvent.mRouterFingerPrint.setMaxSupportedLinkSpeedMbps( 1680 maxSupportedTxLinkSpeedMbps, maxSupportedRxLinkSpeedMbps); 1681 } 1682 } 1683 } 1684 1685 /** 1686 * End a Connection event record. Call when wifi connection attempt succeeds or fails. 1687 * If a Connection event has not been started and is active when .end is called, then this 1688 * method will do nothing. 1689 * 1690 * @param level2FailureCode Level 2 failure code returned by supplicant 1691 * @param connectivityFailureCode WifiMetricsProto.ConnectionEvent.HLF_X 1692 * @param level2FailureReason Breakdown of level2FailureCode with more detailed reason 1693 */ endConnectionEvent(int level2FailureCode, int connectivityFailureCode, int level2FailureReason)1694 public void endConnectionEvent(int level2FailureCode, int connectivityFailureCode, 1695 int level2FailureReason) { 1696 synchronized (mLock) { 1697 if (mCurrentConnectionEvent != null) { 1698 boolean result = (level2FailureCode == 1) 1699 && (connectivityFailureCode == WifiMetricsProto.ConnectionEvent.HLF_NONE); 1700 mCurrentConnectionEvent.mConnectionEvent.connectionResult = result ? 1 : 0; 1701 mCurrentConnectionEvent.mRealEndTime = mClock.getElapsedSinceBootMillis(); 1702 mCurrentConnectionEvent.mConnectionEvent.durationTakenToConnectMillis = (int) 1703 (mCurrentConnectionEvent.mRealEndTime 1704 - mCurrentConnectionEvent.mRealStartTime); 1705 mCurrentConnectionEvent.mConnectionEvent.level2FailureCode = level2FailureCode; 1706 mCurrentConnectionEvent.mConnectionEvent.connectivityLevelFailureCode = 1707 connectivityFailureCode; 1708 mCurrentConnectionEvent.mConnectionEvent.level2FailureReason = level2FailureReason; 1709 1710 // Write metrics to statsd 1711 int wwFailureCode = getConnectionResultFailureCode(level2FailureCode, 1712 level2FailureReason); 1713 if (wwFailureCode != -1) { 1714 WifiStatsLog.write(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED, result, 1715 wwFailureCode, mCurrentConnectionEvent.mConnectionEvent.signalStrength); 1716 } 1717 // ConnectionEvent already added to ConnectionEvents List. Safe to null current here 1718 mCurrentConnectionEvent = null; 1719 if (!result) { 1720 mScanResultRssiTimestampMillis = -1; 1721 } 1722 mWifiStatusBuilder.setConnected(result); 1723 } 1724 } 1725 } 1726 getConnectionResultFailureCode(int level2FailureCode, int level2FailureReason)1727 private int getConnectionResultFailureCode(int level2FailureCode, int level2FailureReason) { 1728 switch (level2FailureCode) { 1729 case ConnectionEvent.FAILURE_NONE: 1730 return WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__FAILURE_CODE__FAILURE_UNKNOWN; 1731 case ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT: 1732 return WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__FAILURE_CODE__FAILURE_ASSOCIATION_TIMEOUT; 1733 case ConnectionEvent.FAILURE_ASSOCIATION_REJECTION: 1734 return WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__FAILURE_CODE__FAILURE_ASSOCIATION_REJECTION; 1735 case ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE: 1736 switch (level2FailureReason) { 1737 case WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_EAP_FAILURE: 1738 return WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__FAILURE_CODE__FAILURE_AUTHENTICATION_EAP; 1739 case WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_WRONG_PSWD: 1740 return -1; 1741 default: 1742 return WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__FAILURE_CODE__FAILURE_AUTHENTICATION_GENERAL; 1743 } 1744 case ConnectionEvent.FAILURE_DHCP: 1745 return WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__FAILURE_CODE__FAILURE_DHCP; 1746 case ConnectionEvent.FAILURE_NETWORK_DISCONNECTION: 1747 return WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__FAILURE_CODE__FAILURE_NETWORK_DISCONNECTION; 1748 case ConnectionEvent.FAILURE_ROAM_TIMEOUT: 1749 return WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__FAILURE_CODE__FAILURE_ROAM_TIMEOUT; 1750 case ConnectionEvent.FAILURE_NEW_CONNECTION_ATTEMPT: 1751 case ConnectionEvent.FAILURE_REDUNDANT_CONNECTION_ATTEMPT: 1752 return -1; 1753 default: 1754 return WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__FAILURE_CODE__FAILURE_UNKNOWN; 1755 } 1756 } 1757 1758 /** 1759 * Set ConnectionEvent DTIM Interval (if set), and 802.11 Connection mode, from NetworkDetail 1760 */ updateMetricsFromNetworkDetail(NetworkDetail networkDetail)1761 private void updateMetricsFromNetworkDetail(NetworkDetail networkDetail) { 1762 int dtimInterval = networkDetail.getDtimInterval(); 1763 if (dtimInterval > 0) { 1764 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.dtim = 1765 dtimInterval; 1766 } 1767 int connectionWifiMode; 1768 switch (networkDetail.getWifiMode()) { 1769 case InformationElementUtil.WifiMode.MODE_UNDEFINED: 1770 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_UNKNOWN; 1771 break; 1772 case InformationElementUtil.WifiMode.MODE_11A: 1773 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_A; 1774 break; 1775 case InformationElementUtil.WifiMode.MODE_11B: 1776 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_B; 1777 break; 1778 case InformationElementUtil.WifiMode.MODE_11G: 1779 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_G; 1780 break; 1781 case InformationElementUtil.WifiMode.MODE_11N: 1782 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_N; 1783 break; 1784 case InformationElementUtil.WifiMode.MODE_11AC : 1785 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_AC; 1786 break; 1787 case InformationElementUtil.WifiMode.MODE_11AX : 1788 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_AX; 1789 break; 1790 default: 1791 connectionWifiMode = WifiMetricsProto.RouterFingerPrint.ROUTER_TECH_OTHER; 1792 break; 1793 } 1794 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto 1795 .routerTechnology = connectionWifiMode; 1796 1797 if (networkDetail.isMboSupported()) { 1798 mWifiLogProto.numConnectToNetworkSupportingMbo++; 1799 if (networkDetail.isOceSupported()) { 1800 mWifiLogProto.numConnectToNetworkSupportingOce++; 1801 } 1802 } 1803 } 1804 1805 /** 1806 * Set ConnectionEvent RSSI and authentication type from ScanResult 1807 */ updateMetricsFromScanResult(ScanResult scanResult)1808 private void updateMetricsFromScanResult(ScanResult scanResult) { 1809 mCurrentConnectionEvent.mConnectionEvent.signalStrength = scanResult.level; 1810 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication = 1811 WifiMetricsProto.RouterFingerPrint.AUTH_OPEN; 1812 mCurrentConnectionEvent.mConfigBssid = scanResult.BSSID; 1813 if (scanResult.capabilities != null) { 1814 if (ScanResultUtil.isScanResultForWepNetwork(scanResult)) { 1815 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication = 1816 WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL; 1817 } else if (ScanResultUtil.isScanResultForPskNetwork(scanResult) 1818 || ScanResultUtil.isScanResultForSaeNetwork(scanResult)) { 1819 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication = 1820 WifiMetricsProto.RouterFingerPrint.AUTH_PERSONAL; 1821 } else if (ScanResultUtil.isScanResultForEapNetwork(scanResult) 1822 || ScanResultUtil.isScanResultForEapSuiteBNetwork(scanResult)) { 1823 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.authentication = 1824 WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE; 1825 } 1826 } 1827 mCurrentConnectionEvent.mRouterFingerPrint.mRouterFingerPrintProto.channelInfo = 1828 scanResult.frequency; 1829 } 1830 setIsLocationEnabled(boolean enabled)1831 void setIsLocationEnabled(boolean enabled) { 1832 synchronized (mLock) { 1833 mWifiLogProto.isLocationEnabled = enabled; 1834 } 1835 } 1836 setIsScanningAlwaysEnabled(boolean enabled)1837 void setIsScanningAlwaysEnabled(boolean enabled) { 1838 synchronized (mLock) { 1839 mWifiLogProto.isScanningAlwaysEnabled = enabled; 1840 } 1841 } 1842 1843 /** 1844 * Developer options toggle value for verbose logging. 1845 */ setVerboseLoggingEnabled(boolean enabled)1846 public void setVerboseLoggingEnabled(boolean enabled) { 1847 synchronized (mLock) { 1848 mWifiLogProto.isVerboseLoggingEnabled = enabled; 1849 } 1850 } 1851 1852 /** 1853 * Developer options toggle value for enhanced MAC randomization. 1854 */ setEnhancedMacRandomizationForceEnabled(boolean enabled)1855 public void setEnhancedMacRandomizationForceEnabled(boolean enabled) { 1856 synchronized (mLock) { 1857 mWifiLogProto.isEnhancedMacRandomizationForceEnabled = enabled; 1858 } 1859 } 1860 1861 /** 1862 * Wifi wake feature toggle. 1863 */ setWifiWakeEnabled(boolean enabled)1864 public void setWifiWakeEnabled(boolean enabled) { 1865 synchronized (mLock) { 1866 mWifiLogProto.isWifiWakeEnabled = enabled; 1867 } 1868 } 1869 1870 /** 1871 * Increment Non Empty Scan Results count 1872 */ incrementNonEmptyScanResultCount()1873 public void incrementNonEmptyScanResultCount() { 1874 if (DBG) Log.v(TAG, "incrementNonEmptyScanResultCount"); 1875 synchronized (mLock) { 1876 mWifiLogProto.numNonEmptyScanResults++; 1877 } 1878 } 1879 1880 /** 1881 * Increment Empty Scan Results count 1882 */ incrementEmptyScanResultCount()1883 public void incrementEmptyScanResultCount() { 1884 if (DBG) Log.v(TAG, "incrementEmptyScanResultCount"); 1885 synchronized (mLock) { 1886 mWifiLogProto.numEmptyScanResults++; 1887 } 1888 } 1889 1890 /** 1891 * Increment background scan count 1892 */ incrementBackgroundScanCount()1893 public void incrementBackgroundScanCount() { 1894 if (DBG) Log.v(TAG, "incrementBackgroundScanCount"); 1895 synchronized (mLock) { 1896 mWifiLogProto.numBackgroundScans++; 1897 } 1898 } 1899 1900 /** 1901 * Get Background scan count 1902 */ getBackgroundScanCount()1903 public int getBackgroundScanCount() { 1904 synchronized (mLock) { 1905 return mWifiLogProto.numBackgroundScans; 1906 } 1907 } 1908 1909 /** 1910 * Increment oneshot scan count, and the associated WifiSystemScanStateCount entry 1911 */ incrementOneshotScanCount()1912 public void incrementOneshotScanCount() { 1913 synchronized (mLock) { 1914 mWifiLogProto.numOneshotScans++; 1915 } 1916 incrementWifiSystemScanStateCount(mWifiState, mScreenOn); 1917 } 1918 1919 /** 1920 * Increment the count of oneshot scans that include DFS channels. 1921 */ incrementOneshotScanWithDfsCount()1922 public void incrementOneshotScanWithDfsCount() { 1923 synchronized (mLock) { 1924 mWifiLogProto.numOneshotHasDfsChannelScans++; 1925 } 1926 } 1927 1928 /** 1929 * Increment connectivity oneshot scan count. 1930 */ incrementConnectivityOneshotScanCount()1931 public void incrementConnectivityOneshotScanCount() { 1932 synchronized (mLock) { 1933 mWifiLogProto.numConnectivityOneshotScans++; 1934 } 1935 } 1936 1937 /** 1938 * Get oneshot scan count 1939 */ getOneshotScanCount()1940 public int getOneshotScanCount() { 1941 synchronized (mLock) { 1942 return mWifiLogProto.numOneshotScans; 1943 } 1944 } 1945 1946 /** 1947 * Get connectivity oneshot scan count 1948 */ getConnectivityOneshotScanCount()1949 public int getConnectivityOneshotScanCount() { 1950 synchronized (mLock) { 1951 return mWifiLogProto.numConnectivityOneshotScans; 1952 } 1953 } 1954 1955 /** 1956 * Get the count of oneshot scan requests that included DFS channels. 1957 */ getOneshotScanWithDfsCount()1958 public int getOneshotScanWithDfsCount() { 1959 synchronized (mLock) { 1960 return mWifiLogProto.numOneshotHasDfsChannelScans; 1961 } 1962 } 1963 1964 /** 1965 * Increment oneshot scan count for external apps. 1966 */ incrementExternalAppOneshotScanRequestsCount()1967 public void incrementExternalAppOneshotScanRequestsCount() { 1968 synchronized (mLock) { 1969 mWifiLogProto.numExternalAppOneshotScanRequests++; 1970 } 1971 } 1972 /** 1973 * Increment oneshot scan throttle count for external foreground apps. 1974 */ incrementExternalForegroundAppOneshotScanRequestsThrottledCount()1975 public void incrementExternalForegroundAppOneshotScanRequestsThrottledCount() { 1976 synchronized (mLock) { 1977 mWifiLogProto.numExternalForegroundAppOneshotScanRequestsThrottled++; 1978 } 1979 } 1980 1981 /** 1982 * Increment oneshot scan throttle count for external background apps. 1983 */ incrementExternalBackgroundAppOneshotScanRequestsThrottledCount()1984 public void incrementExternalBackgroundAppOneshotScanRequestsThrottledCount() { 1985 synchronized (mLock) { 1986 mWifiLogProto.numExternalBackgroundAppOneshotScanRequestsThrottled++; 1987 } 1988 } 1989 returnCodeToString(int scanReturnCode)1990 private String returnCodeToString(int scanReturnCode) { 1991 switch(scanReturnCode){ 1992 case WifiMetricsProto.WifiLog.SCAN_UNKNOWN: 1993 return "SCAN_UNKNOWN"; 1994 case WifiMetricsProto.WifiLog.SCAN_SUCCESS: 1995 return "SCAN_SUCCESS"; 1996 case WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED: 1997 return "SCAN_FAILURE_INTERRUPTED"; 1998 case WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION: 1999 return "SCAN_FAILURE_INVALID_CONFIGURATION"; 2000 case WifiMetricsProto.WifiLog.FAILURE_WIFI_DISABLED: 2001 return "FAILURE_WIFI_DISABLED"; 2002 default: 2003 return "<UNKNOWN>"; 2004 } 2005 } 2006 2007 /** 2008 * Increment count of scan return code occurrence 2009 * 2010 * @param scanReturnCode Return code from scan attempt WifiMetricsProto.WifiLog.SCAN_X 2011 */ incrementScanReturnEntry(int scanReturnCode, int countToAdd)2012 public void incrementScanReturnEntry(int scanReturnCode, int countToAdd) { 2013 synchronized (mLock) { 2014 if (DBG) Log.v(TAG, "incrementScanReturnEntry " + returnCodeToString(scanReturnCode)); 2015 int entry = mScanReturnEntries.get(scanReturnCode); 2016 entry += countToAdd; 2017 mScanReturnEntries.put(scanReturnCode, entry); 2018 } 2019 } 2020 /** 2021 * Get the count of this scanReturnCode 2022 * @param scanReturnCode that we are getting the count for 2023 */ getScanReturnEntry(int scanReturnCode)2024 public int getScanReturnEntry(int scanReturnCode) { 2025 synchronized (mLock) { 2026 return mScanReturnEntries.get(scanReturnCode); 2027 } 2028 } 2029 wifiSystemStateToString(int state)2030 private String wifiSystemStateToString(int state) { 2031 switch(state){ 2032 case WifiMetricsProto.WifiLog.WIFI_UNKNOWN: 2033 return "WIFI_UNKNOWN"; 2034 case WifiMetricsProto.WifiLog.WIFI_DISABLED: 2035 return "WIFI_DISABLED"; 2036 case WifiMetricsProto.WifiLog.WIFI_DISCONNECTED: 2037 return "WIFI_DISCONNECTED"; 2038 case WifiMetricsProto.WifiLog.WIFI_ASSOCIATED: 2039 return "WIFI_ASSOCIATED"; 2040 default: 2041 return "default"; 2042 } 2043 } 2044 2045 /** 2046 * Increments the count of scans initiated by each wifi state, accounts for screenOn/Off 2047 * 2048 * @param state State of the system when scan was initiated, see WifiMetricsProto.WifiLog.WIFI_X 2049 * @param screenOn Is the screen on 2050 */ incrementWifiSystemScanStateCount(int state, boolean screenOn)2051 public void incrementWifiSystemScanStateCount(int state, boolean screenOn) { 2052 synchronized (mLock) { 2053 if (DBG) { 2054 Log.v(TAG, "incrementWifiSystemScanStateCount " + wifiSystemStateToString(state) 2055 + " " + screenOn); 2056 } 2057 int index = (state * 2) + (screenOn ? SCREEN_ON : SCREEN_OFF); 2058 int entry = mWifiSystemStateEntries.get(index); 2059 entry++; 2060 mWifiSystemStateEntries.put(index, entry); 2061 } 2062 } 2063 2064 /** 2065 * Get the count of this system State Entry 2066 */ getSystemStateCount(int state, boolean screenOn)2067 public int getSystemStateCount(int state, boolean screenOn) { 2068 synchronized (mLock) { 2069 int index = state * 2 + (screenOn ? SCREEN_ON : SCREEN_OFF); 2070 return mWifiSystemStateEntries.get(index); 2071 } 2072 } 2073 2074 /** 2075 * Increment number of times the Watchdog of Last Resort triggered, resetting the wifi stack 2076 */ incrementNumLastResortWatchdogTriggers()2077 public void incrementNumLastResortWatchdogTriggers() { 2078 synchronized (mLock) { 2079 mWifiLogProto.numLastResortWatchdogTriggers++; 2080 } 2081 } 2082 /** 2083 * @param count number of networks over bad association threshold when watchdog triggered 2084 */ addCountToNumLastResortWatchdogBadAssociationNetworksTotal(int count)2085 public void addCountToNumLastResortWatchdogBadAssociationNetworksTotal(int count) { 2086 synchronized (mLock) { 2087 mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal += count; 2088 } 2089 } 2090 /** 2091 * @param count number of networks over bad authentication threshold when watchdog triggered 2092 */ addCountToNumLastResortWatchdogBadAuthenticationNetworksTotal(int count)2093 public void addCountToNumLastResortWatchdogBadAuthenticationNetworksTotal(int count) { 2094 synchronized (mLock) { 2095 mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal += count; 2096 } 2097 } 2098 /** 2099 * @param count number of networks over bad dhcp threshold when watchdog triggered 2100 */ addCountToNumLastResortWatchdogBadDhcpNetworksTotal(int count)2101 public void addCountToNumLastResortWatchdogBadDhcpNetworksTotal(int count) { 2102 synchronized (mLock) { 2103 mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal += count; 2104 } 2105 } 2106 /** 2107 * @param count number of networks over bad other threshold when watchdog triggered 2108 */ addCountToNumLastResortWatchdogBadOtherNetworksTotal(int count)2109 public void addCountToNumLastResortWatchdogBadOtherNetworksTotal(int count) { 2110 synchronized (mLock) { 2111 mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal += count; 2112 } 2113 } 2114 /** 2115 * @param count number of networks seen when watchdog triggered 2116 */ addCountToNumLastResortWatchdogAvailableNetworksTotal(int count)2117 public void addCountToNumLastResortWatchdogAvailableNetworksTotal(int count) { 2118 synchronized (mLock) { 2119 mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal += count; 2120 } 2121 } 2122 /** 2123 * Increment count of triggers with atleast one bad association network 2124 */ incrementNumLastResortWatchdogTriggersWithBadAssociation()2125 public void incrementNumLastResortWatchdogTriggersWithBadAssociation() { 2126 synchronized (mLock) { 2127 mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation++; 2128 } 2129 } 2130 /** 2131 * Increment count of triggers with atleast one bad authentication network 2132 */ incrementNumLastResortWatchdogTriggersWithBadAuthentication()2133 public void incrementNumLastResortWatchdogTriggersWithBadAuthentication() { 2134 synchronized (mLock) { 2135 mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication++; 2136 } 2137 } 2138 /** 2139 * Increment count of triggers with atleast one bad dhcp network 2140 */ incrementNumLastResortWatchdogTriggersWithBadDhcp()2141 public void incrementNumLastResortWatchdogTriggersWithBadDhcp() { 2142 synchronized (mLock) { 2143 mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp++; 2144 } 2145 } 2146 /** 2147 * Increment count of triggers with atleast one bad other network 2148 */ incrementNumLastResortWatchdogTriggersWithBadOther()2149 public void incrementNumLastResortWatchdogTriggersWithBadOther() { 2150 synchronized (mLock) { 2151 mWifiLogProto.numLastResortWatchdogTriggersWithBadOther++; 2152 } 2153 } 2154 2155 /** 2156 * Increment number of times connectivity watchdog confirmed pno is working 2157 */ incrementNumConnectivityWatchdogPnoGood()2158 public void incrementNumConnectivityWatchdogPnoGood() { 2159 synchronized (mLock) { 2160 mWifiLogProto.numConnectivityWatchdogPnoGood++; 2161 } 2162 } 2163 /** 2164 * Increment number of times connectivity watchdog found pno not working 2165 */ incrementNumConnectivityWatchdogPnoBad()2166 public void incrementNumConnectivityWatchdogPnoBad() { 2167 synchronized (mLock) { 2168 mWifiLogProto.numConnectivityWatchdogPnoBad++; 2169 } 2170 } 2171 /** 2172 * Increment number of times connectivity watchdog confirmed background scan is working 2173 */ incrementNumConnectivityWatchdogBackgroundGood()2174 public void incrementNumConnectivityWatchdogBackgroundGood() { 2175 synchronized (mLock) { 2176 mWifiLogProto.numConnectivityWatchdogBackgroundGood++; 2177 } 2178 } 2179 /** 2180 * Increment number of times connectivity watchdog found background scan not working 2181 */ incrementNumConnectivityWatchdogBackgroundBad()2182 public void incrementNumConnectivityWatchdogBackgroundBad() { 2183 synchronized (mLock) { 2184 mWifiLogProto.numConnectivityWatchdogBackgroundBad++; 2185 } 2186 } 2187 2188 /** 2189 * Increment various poll related metrics, and cache performance data for StaEvent logging 2190 */ handlePollResult(WifiInfo wifiInfo)2191 public void handlePollResult(WifiInfo wifiInfo) { 2192 mLastPollRssi = wifiInfo.getRssi(); 2193 mLastPollLinkSpeed = wifiInfo.getLinkSpeed(); 2194 mLastPollFreq = wifiInfo.getFrequency(); 2195 incrementRssiPollRssiCount(mLastPollFreq, mLastPollRssi); 2196 incrementLinkSpeedCount(mLastPollLinkSpeed, mLastPollRssi); 2197 mLastPollRxLinkSpeed = wifiInfo.getRxLinkSpeedMbps(); 2198 incrementTxLinkSpeedBandCount(mLastPollLinkSpeed, mLastPollFreq); 2199 incrementRxLinkSpeedBandCount(mLastPollRxLinkSpeed, mLastPollFreq); 2200 mWifiStatusBuilder.setRssi(mLastPollRssi); 2201 mWifiStatusBuilder.setNetworkId(wifiInfo.getNetworkId()); 2202 } 2203 2204 /** 2205 * Increment occurence count of RSSI level from RSSI poll for the given frequency. 2206 * @param frequency (MHz) 2207 * @param rssi 2208 */ 2209 @VisibleForTesting incrementRssiPollRssiCount(int frequency, int rssi)2210 public void incrementRssiPollRssiCount(int frequency, int rssi) { 2211 if (!(rssi >= MIN_RSSI_POLL && rssi <= MAX_RSSI_POLL)) { 2212 return; 2213 } 2214 synchronized (mLock) { 2215 if (!mRssiPollCountsMap.containsKey(frequency)) { 2216 mRssiPollCountsMap.put(frequency, new SparseIntArray()); 2217 } 2218 SparseIntArray sparseIntArray = mRssiPollCountsMap.get(frequency); 2219 int count = sparseIntArray.get(rssi); 2220 sparseIntArray.put(rssi, count + 1); 2221 maybeIncrementRssiDeltaCount(rssi - mScanResultRssi); 2222 } 2223 } 2224 2225 /** 2226 * Increment occurence count of difference between scan result RSSI and the first RSSI poll. 2227 * Ignores rssi values outside the bounds of [MIN_RSSI_DELTA, MAX_RSSI_DELTA] 2228 * mLock must be held when calling this method. 2229 */ maybeIncrementRssiDeltaCount(int rssi)2230 private void maybeIncrementRssiDeltaCount(int rssi) { 2231 // Check if this RSSI poll is close enough to a scan result RSSI to log a delta value 2232 if (mScanResultRssiTimestampMillis >= 0) { 2233 long timeDelta = mClock.getElapsedSinceBootMillis() - mScanResultRssiTimestampMillis; 2234 if (timeDelta <= TIMEOUT_RSSI_DELTA_MILLIS) { 2235 if (rssi >= MIN_RSSI_DELTA && rssi <= MAX_RSSI_DELTA) { 2236 int count = mRssiDeltaCounts.get(rssi); 2237 mRssiDeltaCounts.put(rssi, count + 1); 2238 } 2239 } 2240 mScanResultRssiTimestampMillis = -1; 2241 } 2242 } 2243 2244 /** 2245 * Increment occurrence count of link speed. 2246 * Ignores link speed values that are lower than MIN_LINK_SPEED_MBPS 2247 * and rssi values outside the bounds of [MIN_RSSI_POLL, MAX_RSSI_POLL] 2248 */ 2249 @VisibleForTesting incrementLinkSpeedCount(int linkSpeed, int rssi)2250 public void incrementLinkSpeedCount(int linkSpeed, int rssi) { 2251 if (!(mContext.getResources().getBoolean(R.bool.config_wifiLinkSpeedMetricsEnabled) 2252 && linkSpeed >= MIN_LINK_SPEED_MBPS 2253 && rssi >= MIN_RSSI_POLL 2254 && rssi <= MAX_RSSI_POLL)) { 2255 return; 2256 } 2257 synchronized (mLock) { 2258 LinkSpeedCount linkSpeedCount = mLinkSpeedCounts.get(linkSpeed); 2259 if (linkSpeedCount == null) { 2260 linkSpeedCount = new LinkSpeedCount(); 2261 linkSpeedCount.linkSpeedMbps = linkSpeed; 2262 mLinkSpeedCounts.put(linkSpeed, linkSpeedCount); 2263 } 2264 linkSpeedCount.count++; 2265 linkSpeedCount.rssiSumDbm += Math.abs(rssi); 2266 linkSpeedCount.rssiSumOfSquaresDbmSq += rssi * rssi; 2267 } 2268 } 2269 2270 /** 2271 * Increment occurrence count of Tx link speed for operating sub-band 2272 * Ignores link speed values that are lower than MIN_LINK_SPEED_MBPS 2273 * @param txLinkSpeed PHY layer Tx link speed in Mbps 2274 * @param frequency Channel frequency of beacon frames in MHz 2275 */ 2276 @VisibleForTesting incrementTxLinkSpeedBandCount(int txLinkSpeed, int frequency)2277 public void incrementTxLinkSpeedBandCount(int txLinkSpeed, int frequency) { 2278 if (!(mContext.getResources().getBoolean(R.bool.config_wifiLinkSpeedMetricsEnabled) 2279 && txLinkSpeed >= MIN_LINK_SPEED_MBPS)) { 2280 return; 2281 } 2282 synchronized (mLock) { 2283 if (ScanResult.is24GHz(frequency)) { 2284 mTxLinkSpeedCount2g.increment(txLinkSpeed); 2285 } else if (frequency <= KnownBandsChannelHelper.BAND_5_GHZ_LOW_END_FREQ) { 2286 mTxLinkSpeedCount5gLow.increment(txLinkSpeed); 2287 } else if (frequency <= KnownBandsChannelHelper.BAND_5_GHZ_MID_END_FREQ) { 2288 mTxLinkSpeedCount5gMid.increment(txLinkSpeed); 2289 } else if (frequency <= KnownBandsChannelHelper.BAND_5_GHZ_HIGH_END_FREQ) { 2290 mTxLinkSpeedCount5gHigh.increment(txLinkSpeed); 2291 } else if (frequency <= KnownBandsChannelHelper.BAND_6_GHZ_LOW_END_FREQ) { 2292 mTxLinkSpeedCount6gLow.increment(txLinkSpeed); 2293 } else if (frequency <= KnownBandsChannelHelper.BAND_6_GHZ_MID_END_FREQ) { 2294 mTxLinkSpeedCount6gMid.increment(txLinkSpeed); 2295 } else if (frequency <= KnownBandsChannelHelper.BAND_6_GHZ_HIGH_END_FREQ) { 2296 mTxLinkSpeedCount6gHigh.increment(txLinkSpeed); 2297 } 2298 } 2299 } 2300 2301 /** 2302 * Increment occurrence count of Rx link speed for operating sub-band 2303 * Ignores link speed values that are lower than MIN_LINK_SPEED_MBPS 2304 * @param rxLinkSpeed PHY layer Tx link speed in Mbps 2305 * @param frequency Channel frequency of beacon frames in MHz 2306 */ 2307 @VisibleForTesting incrementRxLinkSpeedBandCount(int rxLinkSpeed, int frequency)2308 public void incrementRxLinkSpeedBandCount(int rxLinkSpeed, int frequency) { 2309 if (!(mContext.getResources().getBoolean(R.bool.config_wifiLinkSpeedMetricsEnabled) 2310 && rxLinkSpeed >= MIN_LINK_SPEED_MBPS)) { 2311 return; 2312 } 2313 synchronized (mLock) { 2314 if (ScanResult.is24GHz(frequency)) { 2315 mRxLinkSpeedCount2g.increment(rxLinkSpeed); 2316 } else if (frequency <= KnownBandsChannelHelper.BAND_5_GHZ_LOW_END_FREQ) { 2317 mRxLinkSpeedCount5gLow.increment(rxLinkSpeed); 2318 } else if (frequency <= KnownBandsChannelHelper.BAND_5_GHZ_MID_END_FREQ) { 2319 mRxLinkSpeedCount5gMid.increment(rxLinkSpeed); 2320 } else if (frequency <= KnownBandsChannelHelper.BAND_5_GHZ_HIGH_END_FREQ) { 2321 mRxLinkSpeedCount5gHigh.increment(rxLinkSpeed); 2322 } else if (frequency <= KnownBandsChannelHelper.BAND_6_GHZ_LOW_END_FREQ) { 2323 mRxLinkSpeedCount6gLow.increment(rxLinkSpeed); 2324 } else if (frequency <= KnownBandsChannelHelper.BAND_6_GHZ_MID_END_FREQ) { 2325 mRxLinkSpeedCount6gMid.increment(rxLinkSpeed); 2326 } else if (frequency <= KnownBandsChannelHelper.BAND_6_GHZ_HIGH_END_FREQ) { 2327 mRxLinkSpeedCount6gHigh.increment(rxLinkSpeed); 2328 } 2329 } 2330 } 2331 2332 /** 2333 * Increment occurrence count of channel utilization 2334 * @param channelUtilization Channel utilization of current network 2335 * @param frequency Channel frequency of current network 2336 */ 2337 @VisibleForTesting incrementChannelUtilizationCount(int channelUtilization, int frequency)2338 public void incrementChannelUtilizationCount(int channelUtilization, int frequency) { 2339 if (channelUtilization < InformationElementUtil.BssLoad.MIN_CHANNEL_UTILIZATION 2340 || channelUtilization > InformationElementUtil.BssLoad.MAX_CHANNEL_UTILIZATION) { 2341 return; 2342 } 2343 synchronized (mLock) { 2344 if (ScanResult.is24GHz(frequency)) { 2345 mChannelUtilizationHistogram2G.increment(channelUtilization); 2346 } else { 2347 mChannelUtilizationHistogramAbove2G.increment(channelUtilization); 2348 } 2349 } 2350 } 2351 2352 /** 2353 * Increment occurrence count of Tx and Rx throughput 2354 * @param txThroughputKbps Tx throughput of current network in Kbps 2355 * @param rxThroughputKbps Rx throughput of current network in Kbps 2356 * @param frequency Channel frequency of current network in MHz 2357 */ 2358 @VisibleForTesting incrementThroughputKbpsCount(int txThroughputKbps, int rxThroughputKbps, int frequency)2359 public void incrementThroughputKbpsCount(int txThroughputKbps, int rxThroughputKbps, 2360 int frequency) { 2361 synchronized (mLock) { 2362 if (ScanResult.is24GHz(frequency)) { 2363 if (txThroughputKbps >= 0) { 2364 mTxThroughputMbpsHistogram2G.increment(txThroughputKbps / 1000); 2365 } 2366 if (rxThroughputKbps >= 0) { 2367 mRxThroughputMbpsHistogram2G.increment(rxThroughputKbps / 1000); 2368 } 2369 } else { 2370 if (txThroughputKbps >= 0) { 2371 mTxThroughputMbpsHistogramAbove2G.increment(txThroughputKbps / 1000); 2372 } 2373 if (rxThroughputKbps >= 0) { 2374 mRxThroughputMbpsHistogramAbove2G.increment(rxThroughputKbps / 1000); 2375 } 2376 } 2377 mWifiStatusBuilder.setEstimatedTxKbps(txThroughputKbps); 2378 mWifiStatusBuilder.setEstimatedRxKbps(rxThroughputKbps); 2379 } 2380 } 2381 2382 /** 2383 * Increment count of Watchdog successes. 2384 */ incrementNumLastResortWatchdogSuccesses()2385 public void incrementNumLastResortWatchdogSuccesses() { 2386 synchronized (mLock) { 2387 mWifiLogProto.numLastResortWatchdogSuccesses++; 2388 } 2389 } 2390 2391 /** 2392 * Increment the count of network connection failures that happened after watchdog has been 2393 * triggered. 2394 */ incrementWatchdogTotalConnectionFailureCountAfterTrigger()2395 public void incrementWatchdogTotalConnectionFailureCountAfterTrigger() { 2396 synchronized (mLock) { 2397 mWifiLogProto.watchdogTotalConnectionFailureCountAfterTrigger++; 2398 } 2399 } 2400 2401 /** 2402 * Sets the time taken for wifi to connect after a watchdog triggers a restart. 2403 * @param milliseconds 2404 */ setWatchdogSuccessTimeDurationMs(long ms)2405 public void setWatchdogSuccessTimeDurationMs(long ms) { 2406 synchronized (mLock) { 2407 mWifiLogProto.watchdogTriggerToConnectionSuccessDurationMs = ms; 2408 } 2409 } 2410 2411 /** 2412 * Increments the count of alerts by alert reason. 2413 * 2414 * @param reason The cause of the alert. The reason values are driver-specific. 2415 */ incrementAlertReasonCount(int reason)2416 private void incrementAlertReasonCount(int reason) { 2417 if (reason > WifiLoggerHal.WIFI_ALERT_REASON_MAX 2418 || reason < WifiLoggerHal.WIFI_ALERT_REASON_MIN) { 2419 reason = WifiLoggerHal.WIFI_ALERT_REASON_RESERVED; 2420 } 2421 synchronized (mLock) { 2422 int alertCount = mWifiAlertReasonCounts.get(reason); 2423 mWifiAlertReasonCounts.put(reason, alertCount + 1); 2424 } 2425 } 2426 2427 /** 2428 * Counts all the different types of networks seen in a set of scan results 2429 */ countScanResults(List<ScanDetail> scanDetails)2430 public void countScanResults(List<ScanDetail> scanDetails) { 2431 if (scanDetails == null) { 2432 return; 2433 } 2434 int totalResults = 0; 2435 int openNetworks = 0; 2436 int personalNetworks = 0; 2437 int enterpriseNetworks = 0; 2438 int hiddenNetworks = 0; 2439 int hotspot2r1Networks = 0; 2440 int hotspot2r2Networks = 0; 2441 int hotspot2r3Networks = 0; 2442 int enhacedOpenNetworks = 0; 2443 int wpa3PersonalNetworks = 0; 2444 int wpa3EnterpriseNetworks = 0; 2445 int wapiPersonalNetworks = 0; 2446 int wapiEnterpriseNetworks = 0; 2447 int mboSupportedNetworks = 0; 2448 int mboCellularDataAwareNetworks = 0; 2449 int oceSupportedNetworks = 0; 2450 int filsSupportedNetworks = 0; 2451 int band6gNetworks = 0; 2452 int standard11axNetworks = 0; 2453 2454 for (ScanDetail scanDetail : scanDetails) { 2455 NetworkDetail networkDetail = scanDetail.getNetworkDetail(); 2456 ScanResult scanResult = scanDetail.getScanResult(); 2457 totalResults++; 2458 if (networkDetail != null) { 2459 if (networkDetail.isHiddenBeaconFrame()) { 2460 hiddenNetworks++; 2461 } 2462 if (networkDetail.getHSRelease() != null) { 2463 if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R1) { 2464 hotspot2r1Networks++; 2465 } else if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R2) { 2466 hotspot2r2Networks++; 2467 } else if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R3) { 2468 hotspot2r3Networks++; 2469 } 2470 } 2471 if (networkDetail.isMboSupported()) { 2472 mboSupportedNetworks++; 2473 if (networkDetail.isMboCellularDataAware()) { 2474 mboCellularDataAwareNetworks++; 2475 } 2476 if (networkDetail.isOceSupported()) { 2477 oceSupportedNetworks++; 2478 } 2479 } 2480 if (networkDetail.getWifiMode() == InformationElementUtil.WifiMode.MODE_11AX) { 2481 standard11axNetworks++; 2482 } 2483 } 2484 if (scanResult != null && scanResult.capabilities != null) { 2485 if (ScanResultUtil.isScanResultForFilsSha256Network(scanResult) 2486 || ScanResultUtil.isScanResultForFilsSha384Network(scanResult)) { 2487 filsSupportedNetworks++; 2488 } 2489 if (scanResult.is6GHz()) { 2490 band6gNetworks++; 2491 } 2492 if (ScanResultUtil.isScanResultForEapSuiteBNetwork(scanResult)) { 2493 wpa3EnterpriseNetworks++; 2494 } else if (ScanResultUtil.isScanResultForWapiPskNetwork(scanResult)) { 2495 wapiPersonalNetworks++; 2496 } else if (ScanResultUtil.isScanResultForWapiCertNetwork(scanResult)) { 2497 wapiEnterpriseNetworks++; 2498 } else if (ScanResultUtil.isScanResultForEapNetwork(scanResult)) { 2499 enterpriseNetworks++; 2500 } else if (ScanResultUtil.isScanResultForSaeNetwork(scanResult)) { 2501 wpa3PersonalNetworks++; 2502 } else if (ScanResultUtil.isScanResultForPskNetwork(scanResult) 2503 || ScanResultUtil.isScanResultForWepNetwork(scanResult)) { 2504 personalNetworks++; 2505 } else if (ScanResultUtil.isScanResultForOweNetwork(scanResult)) { 2506 enhacedOpenNetworks++; 2507 } else { 2508 openNetworks++; 2509 } 2510 } 2511 } 2512 synchronized (mLock) { 2513 mWifiLogProto.numTotalScanResults += totalResults; 2514 mWifiLogProto.numOpenNetworkScanResults += openNetworks; 2515 mWifiLogProto.numLegacyPersonalNetworkScanResults += personalNetworks; 2516 mWifiLogProto.numLegacyEnterpriseNetworkScanResults += enterpriseNetworks; 2517 mWifiLogProto.numEnhancedOpenNetworkScanResults += enhacedOpenNetworks; 2518 mWifiLogProto.numWpa3PersonalNetworkScanResults += wpa3PersonalNetworks; 2519 mWifiLogProto.numWpa3EnterpriseNetworkScanResults += wpa3EnterpriseNetworks; 2520 mWifiLogProto.numWapiPersonalNetworkScanResults += wapiPersonalNetworks; 2521 mWifiLogProto.numWapiEnterpriseNetworkScanResults += wapiEnterpriseNetworks; 2522 mWifiLogProto.numHiddenNetworkScanResults += hiddenNetworks; 2523 mWifiLogProto.numHotspot2R1NetworkScanResults += hotspot2r1Networks; 2524 mWifiLogProto.numHotspot2R2NetworkScanResults += hotspot2r2Networks; 2525 mWifiLogProto.numHotspot2R3NetworkScanResults += hotspot2r3Networks; 2526 mWifiLogProto.numMboSupportedNetworkScanResults += mboSupportedNetworks; 2527 mWifiLogProto.numMboCellularDataAwareNetworkScanResults += mboCellularDataAwareNetworks; 2528 mWifiLogProto.numOceSupportedNetworkScanResults += oceSupportedNetworks; 2529 mWifiLogProto.numFilsSupportedNetworkScanResults += filsSupportedNetworks; 2530 mWifiLogProto.num11AxNetworkScanResults += standard11axNetworks; 2531 mWifiLogProto.num6GNetworkScanResults += band6gNetworks; 2532 mWifiLogProto.numScans++; 2533 } 2534 } 2535 2536 private boolean mWifiWins = false; // Based on scores, use wifi instead of mobile data? 2537 // Based on Wifi usability scores. use wifi instead of mobile data? 2538 private boolean mWifiWinsUsabilityScore = false; 2539 2540 /** 2541 * Increments occurence of a particular wifi score calculated 2542 * in WifiScoreReport by current connected network. Scores are bounded 2543 * within [MIN_WIFI_SCORE, MAX_WIFI_SCORE] to limit size of SparseArray. 2544 * 2545 * Also records events when the current score breaches significant thresholds. 2546 */ incrementWifiScoreCount(int score)2547 public void incrementWifiScoreCount(int score) { 2548 if (score < MIN_WIFI_SCORE || score > MAX_WIFI_SCORE) { 2549 return; 2550 } 2551 synchronized (mLock) { 2552 int count = mWifiScoreCounts.get(score); 2553 mWifiScoreCounts.put(score, count + 1); 2554 2555 boolean wifiWins = mWifiWins; 2556 if (mWifiWins && score < LOW_WIFI_SCORE) { 2557 wifiWins = false; 2558 } else if (!mWifiWins && score > LOW_WIFI_SCORE) { 2559 wifiWins = true; 2560 } 2561 mLastScore = score; 2562 mLastScoreNoReset = score; 2563 if (wifiWins != mWifiWins) { 2564 mWifiWins = wifiWins; 2565 StaEvent event = new StaEvent(); 2566 event.type = StaEvent.TYPE_SCORE_BREACH; 2567 addStaEvent(event); 2568 // Only record the first score breach by checking whether mScoreBreachLowTimeMillis 2569 // has been set to -1 2570 if (!wifiWins && mScoreBreachLowTimeMillis == -1) { 2571 mScoreBreachLowTimeMillis = mClock.getElapsedSinceBootMillis(); 2572 } 2573 } 2574 } 2575 } 2576 2577 /** 2578 * Increments occurence of the results from attempting to start SoftAp. 2579 * Maps the |result| and WifiManager |failureCode| constant to proto defined SoftApStartResult 2580 * codes. 2581 */ incrementSoftApStartResult(boolean result, int failureCode)2582 public void incrementSoftApStartResult(boolean result, int failureCode) { 2583 synchronized (mLock) { 2584 if (result) { 2585 int count = mSoftApManagerReturnCodeCounts.get( 2586 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_STARTED_SUCCESSFULLY); 2587 mSoftApManagerReturnCodeCounts.put( 2588 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_STARTED_SUCCESSFULLY, 2589 count + 1); 2590 return; 2591 } 2592 2593 // now increment failure modes - if not explicitly handled, dump into the general 2594 // error bucket. 2595 if (failureCode == WifiManager.SAP_START_FAILURE_NO_CHANNEL) { 2596 int count = mSoftApManagerReturnCodeCounts.get( 2597 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_NO_CHANNEL); 2598 mSoftApManagerReturnCodeCounts.put( 2599 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_NO_CHANNEL, 2600 count + 1); 2601 } else if (failureCode == WifiManager.SAP_START_FAILURE_UNSUPPORTED_CONFIGURATION) { 2602 int count = mSoftApManagerReturnCodeCounts.get( 2603 WifiMetricsProto.SoftApReturnCodeCount 2604 .SOFT_AP_FAILED_UNSUPPORTED_CONFIGURATION); 2605 mSoftApManagerReturnCodeCounts.put( 2606 WifiMetricsProto.SoftApReturnCodeCount 2607 .SOFT_AP_FAILED_UNSUPPORTED_CONFIGURATION, 2608 count + 1); 2609 } else { 2610 // failure mode not tracked at this time... count as a general error for now. 2611 int count = mSoftApManagerReturnCodeCounts.get( 2612 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_GENERAL_ERROR); 2613 mSoftApManagerReturnCodeCounts.put( 2614 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_GENERAL_ERROR, 2615 count + 1); 2616 } 2617 } 2618 } 2619 2620 /** 2621 * Adds a record indicating the current up state of soft AP 2622 */ addSoftApUpChangedEvent(boolean isUp, int mode, long defaultShutdownTimeoutMillis)2623 public void addSoftApUpChangedEvent(boolean isUp, int mode, long defaultShutdownTimeoutMillis) { 2624 SoftApConnectedClientsEvent event = new SoftApConnectedClientsEvent(); 2625 event.eventType = isUp ? SoftApConnectedClientsEvent.SOFT_AP_UP : 2626 SoftApConnectedClientsEvent.SOFT_AP_DOWN; 2627 event.numConnectedClients = 0; 2628 event.defaultShutdownTimeoutSetting = defaultShutdownTimeoutMillis; 2629 addSoftApConnectedClientsEvent(event, mode); 2630 } 2631 2632 /** 2633 * Adds a record for current number of associated stations to soft AP 2634 */ addSoftApNumAssociatedStationsChangedEvent(int numStations, int mode)2635 public void addSoftApNumAssociatedStationsChangedEvent(int numStations, int mode) { 2636 SoftApConnectedClientsEvent event = new SoftApConnectedClientsEvent(); 2637 event.eventType = SoftApConnectedClientsEvent.NUM_CLIENTS_CHANGED; 2638 event.numConnectedClients = numStations; 2639 addSoftApConnectedClientsEvent(event, mode); 2640 } 2641 2642 /** 2643 * Adds a record to the corresponding event list based on mode param 2644 */ addSoftApConnectedClientsEvent(SoftApConnectedClientsEvent event, int mode)2645 private void addSoftApConnectedClientsEvent(SoftApConnectedClientsEvent event, int mode) { 2646 synchronized (mLock) { 2647 List<SoftApConnectedClientsEvent> softApEventList; 2648 switch (mode) { 2649 case WifiManager.IFACE_IP_MODE_TETHERED: 2650 softApEventList = mSoftApEventListTethered; 2651 break; 2652 case WifiManager.IFACE_IP_MODE_LOCAL_ONLY: 2653 softApEventList = mSoftApEventListLocalOnly; 2654 break; 2655 default: 2656 return; 2657 } 2658 2659 if (softApEventList.size() > MAX_NUM_SOFT_AP_EVENTS) { 2660 return; 2661 } 2662 2663 event.timeStampMillis = mClock.getElapsedSinceBootMillis(); 2664 softApEventList.add(event); 2665 } 2666 } 2667 2668 /** 2669 * Updates current soft AP events with channel info 2670 */ addSoftApChannelSwitchedEvent(int frequency, int bandwidth, int mode)2671 public void addSoftApChannelSwitchedEvent(int frequency, int bandwidth, int mode) { 2672 synchronized (mLock) { 2673 List<SoftApConnectedClientsEvent> softApEventList; 2674 switch (mode) { 2675 case WifiManager.IFACE_IP_MODE_TETHERED: 2676 softApEventList = mSoftApEventListTethered; 2677 break; 2678 case WifiManager.IFACE_IP_MODE_LOCAL_ONLY: 2679 softApEventList = mSoftApEventListLocalOnly; 2680 break; 2681 default: 2682 return; 2683 } 2684 2685 for (int index = softApEventList.size() - 1; index >= 0; index--) { 2686 SoftApConnectedClientsEvent event = softApEventList.get(index); 2687 2688 if (event != null && event.eventType == SoftApConnectedClientsEvent.SOFT_AP_UP) { 2689 event.channelFrequency = frequency; 2690 event.channelBandwidth = bandwidth; 2691 break; 2692 } 2693 } 2694 } 2695 } 2696 2697 /** 2698 * Updates current soft AP events with softap configuration 2699 */ updateSoftApConfiguration(SoftApConfiguration config, int mode)2700 public void updateSoftApConfiguration(SoftApConfiguration config, int mode) { 2701 synchronized (mLock) { 2702 List<SoftApConnectedClientsEvent> softApEventList; 2703 switch (mode) { 2704 case WifiManager.IFACE_IP_MODE_TETHERED: 2705 softApEventList = mSoftApEventListTethered; 2706 break; 2707 case WifiManager.IFACE_IP_MODE_LOCAL_ONLY: 2708 softApEventList = mSoftApEventListLocalOnly; 2709 break; 2710 default: 2711 return; 2712 } 2713 2714 for (int index = softApEventList.size() - 1; index >= 0; index--) { 2715 SoftApConnectedClientsEvent event = softApEventList.get(index); 2716 2717 if (event != null && event.eventType == SoftApConnectedClientsEvent.SOFT_AP_UP) { 2718 event.maxNumClientsSettingInSoftapConfiguration = 2719 config.getMaxNumberOfClients(); 2720 event.shutdownTimeoutSettingInSoftapConfiguration = 2721 config.getShutdownTimeoutMillis(); 2722 event.clientControlIsEnabled = config.isClientControlByUserEnabled(); 2723 break; 2724 } 2725 } 2726 } 2727 } 2728 2729 /** 2730 * Updates current soft AP events with softap capability 2731 */ updateSoftApCapability(SoftApCapability capability, int mode)2732 public void updateSoftApCapability(SoftApCapability capability, int mode) { 2733 synchronized (mLock) { 2734 List<SoftApConnectedClientsEvent> softApEventList; 2735 switch (mode) { 2736 case WifiManager.IFACE_IP_MODE_TETHERED: 2737 softApEventList = mSoftApEventListTethered; 2738 break; 2739 case WifiManager.IFACE_IP_MODE_LOCAL_ONLY: 2740 softApEventList = mSoftApEventListLocalOnly; 2741 break; 2742 default: 2743 return; 2744 } 2745 2746 for (int index = softApEventList.size() - 1; index >= 0; index--) { 2747 SoftApConnectedClientsEvent event = softApEventList.get(index); 2748 if (event != null && event.eventType == SoftApConnectedClientsEvent.SOFT_AP_UP) { 2749 event.maxNumClientsSettingInSoftapCapability = 2750 capability.getMaxSupportedClients(); 2751 break; 2752 } 2753 } 2754 } 2755 } 2756 2757 /** 2758 * Increment number of times the HAL crashed. 2759 */ incrementNumHalCrashes()2760 public void incrementNumHalCrashes() { 2761 synchronized (mLock) { 2762 mWifiLogProto.numHalCrashes++; 2763 } 2764 } 2765 2766 /** 2767 * Increment number of times the Wificond crashed. 2768 */ incrementNumWificondCrashes()2769 public void incrementNumWificondCrashes() { 2770 synchronized (mLock) { 2771 mWifiLogProto.numWificondCrashes++; 2772 } 2773 } 2774 2775 /** 2776 * Increment number of times the supplicant crashed. 2777 */ incrementNumSupplicantCrashes()2778 public void incrementNumSupplicantCrashes() { 2779 synchronized (mLock) { 2780 mWifiLogProto.numSupplicantCrashes++; 2781 } 2782 } 2783 2784 /** 2785 * Increment number of times the hostapd crashed. 2786 */ incrementNumHostapdCrashes()2787 public void incrementNumHostapdCrashes() { 2788 synchronized (mLock) { 2789 mWifiLogProto.numHostapdCrashes++; 2790 } 2791 } 2792 2793 /** 2794 * Increment number of times the wifi on failed due to an error in HAL. 2795 */ incrementNumSetupClientInterfaceFailureDueToHal()2796 public void incrementNumSetupClientInterfaceFailureDueToHal() { 2797 synchronized (mLock) { 2798 mWifiLogProto.numSetupClientInterfaceFailureDueToHal++; 2799 } 2800 } 2801 2802 /** 2803 * Increment number of times the wifi on failed due to an error in wificond. 2804 */ incrementNumSetupClientInterfaceFailureDueToWificond()2805 public void incrementNumSetupClientInterfaceFailureDueToWificond() { 2806 synchronized (mLock) { 2807 mWifiLogProto.numSetupClientInterfaceFailureDueToWificond++; 2808 } 2809 } 2810 2811 /** 2812 * Increment number of times the wifi on failed due to an error in supplicant. 2813 */ incrementNumSetupClientInterfaceFailureDueToSupplicant()2814 public void incrementNumSetupClientInterfaceFailureDueToSupplicant() { 2815 synchronized (mLock) { 2816 mWifiLogProto.numSetupClientInterfaceFailureDueToSupplicant++; 2817 } 2818 } 2819 2820 /** 2821 * Increment number of times the SoftAp on failed due to an error in HAL. 2822 */ incrementNumSetupSoftApInterfaceFailureDueToHal()2823 public void incrementNumSetupSoftApInterfaceFailureDueToHal() { 2824 synchronized (mLock) { 2825 mWifiLogProto.numSetupSoftApInterfaceFailureDueToHal++; 2826 } 2827 } 2828 2829 /** 2830 * Increment number of times the SoftAp on failed due to an error in wificond. 2831 */ incrementNumSetupSoftApInterfaceFailureDueToWificond()2832 public void incrementNumSetupSoftApInterfaceFailureDueToWificond() { 2833 synchronized (mLock) { 2834 mWifiLogProto.numSetupSoftApInterfaceFailureDueToWificond++; 2835 } 2836 } 2837 2838 /** 2839 * Increment number of times the SoftAp on failed due to an error in hostapd. 2840 */ incrementNumSetupSoftApInterfaceFailureDueToHostapd()2841 public void incrementNumSetupSoftApInterfaceFailureDueToHostapd() { 2842 synchronized (mLock) { 2843 mWifiLogProto.numSetupSoftApInterfaceFailureDueToHostapd++; 2844 } 2845 } 2846 2847 /** 2848 * Increment number of times we got client interface down. 2849 */ incrementNumClientInterfaceDown()2850 public void incrementNumClientInterfaceDown() { 2851 synchronized (mLock) { 2852 mWifiLogProto.numClientInterfaceDown++; 2853 } 2854 } 2855 2856 /** 2857 * Increment number of times we got client interface down. 2858 */ incrementNumSoftApInterfaceDown()2859 public void incrementNumSoftApInterfaceDown() { 2860 synchronized (mLock) { 2861 mWifiLogProto.numSoftApInterfaceDown++; 2862 } 2863 } 2864 2865 /** 2866 * Increment number of times Passpoint provider being installed. 2867 */ incrementNumPasspointProviderInstallation()2868 public void incrementNumPasspointProviderInstallation() { 2869 synchronized (mLock) { 2870 mWifiLogProto.numPasspointProviderInstallation++; 2871 } 2872 } 2873 2874 /** 2875 * Increment number of times Passpoint provider is installed successfully. 2876 */ incrementNumPasspointProviderInstallSuccess()2877 public void incrementNumPasspointProviderInstallSuccess() { 2878 synchronized (mLock) { 2879 mWifiLogProto.numPasspointProviderInstallSuccess++; 2880 } 2881 } 2882 2883 /** 2884 * Increment number of times Passpoint provider being uninstalled. 2885 */ incrementNumPasspointProviderUninstallation()2886 public void incrementNumPasspointProviderUninstallation() { 2887 synchronized (mLock) { 2888 mWifiLogProto.numPasspointProviderUninstallation++; 2889 } 2890 } 2891 2892 /** 2893 * Increment number of times Passpoint provider is uninstalled successfully. 2894 */ incrementNumPasspointProviderUninstallSuccess()2895 public void incrementNumPasspointProviderUninstallSuccess() { 2896 synchronized (mLock) { 2897 mWifiLogProto.numPasspointProviderUninstallSuccess++; 2898 } 2899 } 2900 2901 /** 2902 * Increment number of Passpoint providers with no Root CA in their profile. 2903 */ incrementNumPasspointProviderWithNoRootCa()2904 public void incrementNumPasspointProviderWithNoRootCa() { 2905 synchronized (mLock) { 2906 mWifiLogProto.numPasspointProviderWithNoRootCa++; 2907 } 2908 } 2909 2910 /** 2911 * Increment number of Passpoint providers with a self-signed Root CA in their profile. 2912 */ incrementNumPasspointProviderWithSelfSignedRootCa()2913 public void incrementNumPasspointProviderWithSelfSignedRootCa() { 2914 synchronized (mLock) { 2915 mWifiLogProto.numPasspointProviderWithSelfSignedRootCa++; 2916 } 2917 } 2918 2919 /** 2920 * Increment number of Passpoint providers with subscription expiration date in their profile. 2921 */ incrementNumPasspointProviderWithSubscriptionExpiration()2922 public void incrementNumPasspointProviderWithSubscriptionExpiration() { 2923 synchronized (mLock) { 2924 mWifiLogProto.numPasspointProviderWithSubscriptionExpiration++; 2925 } 2926 } 2927 2928 /** 2929 * Increment number of times we detected a radio mode change to MCC. 2930 */ incrementNumRadioModeChangeToMcc()2931 public void incrementNumRadioModeChangeToMcc() { 2932 synchronized (mLock) { 2933 mWifiLogProto.numRadioModeChangeToMcc++; 2934 } 2935 } 2936 2937 /** 2938 * Increment number of times we detected a radio mode change to SCC. 2939 */ incrementNumRadioModeChangeToScc()2940 public void incrementNumRadioModeChangeToScc() { 2941 synchronized (mLock) { 2942 mWifiLogProto.numRadioModeChangeToScc++; 2943 } 2944 } 2945 2946 /** 2947 * Increment number of times we detected a radio mode change to SBS. 2948 */ incrementNumRadioModeChangeToSbs()2949 public void incrementNumRadioModeChangeToSbs() { 2950 synchronized (mLock) { 2951 mWifiLogProto.numRadioModeChangeToSbs++; 2952 } 2953 } 2954 2955 /** 2956 * Increment number of times we detected a radio mode change to DBS. 2957 */ incrementNumRadioModeChangeToDbs()2958 public void incrementNumRadioModeChangeToDbs() { 2959 synchronized (mLock) { 2960 mWifiLogProto.numRadioModeChangeToDbs++; 2961 } 2962 } 2963 2964 /** 2965 * Increment number of times we detected a channel did not satisfy user band preference. 2966 */ incrementNumSoftApUserBandPreferenceUnsatisfied()2967 public void incrementNumSoftApUserBandPreferenceUnsatisfied() { 2968 synchronized (mLock) { 2969 mWifiLogProto.numSoftApUserBandPreferenceUnsatisfied++; 2970 } 2971 } 2972 2973 /** 2974 * Increment N-Way network selection decision histograms: 2975 * Counts the size of various sets of scanDetails within a scan, and increment the occurrence 2976 * of that size for the associated histogram. There are ten histograms generated for each 2977 * combination of: {SSID, BSSID} *{Total, Saved, Open, Saved_or_Open, Passpoint} 2978 * Only performs this count if isFullBand is true, otherwise, increments the partial scan count 2979 */ incrementAvailableNetworksHistograms(List<ScanDetail> scanDetails, boolean isFullBand)2980 public void incrementAvailableNetworksHistograms(List<ScanDetail> scanDetails, 2981 boolean isFullBand) { 2982 synchronized (mLock) { 2983 if (mWifiConfigManager == null || mWifiNetworkSelector == null 2984 || mPasspointManager == null) { 2985 return; 2986 } 2987 if (!isFullBand) { 2988 mWifiLogProto.partialAllSingleScanListenerResults++; 2989 return; 2990 } 2991 Set<ScanResultMatchInfo> ssids = new HashSet<ScanResultMatchInfo>(); 2992 int bssids = 0; 2993 Set<ScanResultMatchInfo> openSsids = new HashSet<ScanResultMatchInfo>(); 2994 int openBssids = 0; 2995 Set<ScanResultMatchInfo> savedSsids = new HashSet<ScanResultMatchInfo>(); 2996 int savedBssids = 0; 2997 // openOrSavedSsids calculated from union of savedSsids & openSsids 2998 int openOrSavedBssids = 0; 2999 Set<PasspointProvider> savedPasspointProviderProfiles = 3000 new HashSet<PasspointProvider>(); 3001 int savedPasspointProviderBssids = 0; 3002 int passpointR1Aps = 0; 3003 int passpointR2Aps = 0; 3004 int passpointR3Aps = 0; 3005 Map<ANQPNetworkKey, Integer> passpointR1UniqueEss = new HashMap<>(); 3006 Map<ANQPNetworkKey, Integer> passpointR2UniqueEss = new HashMap<>(); 3007 Map<ANQPNetworkKey, Integer> passpointR3UniqueEss = new HashMap<>(); 3008 int supporting80211mcAps = 0; 3009 for (ScanDetail scanDetail : scanDetails) { 3010 NetworkDetail networkDetail = scanDetail.getNetworkDetail(); 3011 ScanResult scanResult = scanDetail.getScanResult(); 3012 3013 // statistics to be collected for ALL APs (irrespective of signal power) 3014 if (networkDetail.is80211McResponderSupport()) { 3015 supporting80211mcAps++; 3016 } 3017 3018 ScanResultMatchInfo matchInfo = ScanResultMatchInfo.fromScanResult(scanResult); 3019 List<Pair<PasspointProvider, PasspointMatch>> matchedProviders = null; 3020 if (networkDetail.isInterworking()) { 3021 // Try to match provider, but do not allow new ANQP messages. Use cached data. 3022 matchedProviders = mPasspointManager.matchProvider(scanResult, false); 3023 if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R1) { 3024 passpointR1Aps++; 3025 } else if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R2) { 3026 passpointR2Aps++; 3027 } else if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R3) { 3028 passpointR3Aps++; 3029 } 3030 3031 long bssid = 0; 3032 boolean validBssid = false; 3033 try { 3034 bssid = Utils.parseMac(scanResult.BSSID); 3035 validBssid = true; 3036 } catch (IllegalArgumentException e) { 3037 Log.e(TAG, 3038 "Invalid BSSID provided in the scan result: " + scanResult.BSSID); 3039 } 3040 if (validBssid) { 3041 ANQPNetworkKey uniqueEss = ANQPNetworkKey.buildKey(scanResult.SSID, bssid, 3042 scanResult.hessid, networkDetail.getAnqpDomainID()); 3043 if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R1) { 3044 Integer countObj = passpointR1UniqueEss.get(uniqueEss); 3045 int count = countObj == null ? 0 : countObj; 3046 passpointR1UniqueEss.put(uniqueEss, count + 1); 3047 } else if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R2) { 3048 Integer countObj = passpointR2UniqueEss.get(uniqueEss); 3049 int count = countObj == null ? 0 : countObj; 3050 passpointR2UniqueEss.put(uniqueEss, count + 1); 3051 } else if (networkDetail.getHSRelease() == NetworkDetail.HSRelease.R3) { 3052 Integer countObj = passpointR3UniqueEss.get(uniqueEss); 3053 int count = countObj == null ? 0 : countObj; 3054 passpointR3UniqueEss.put(uniqueEss, count + 1); 3055 } 3056 } 3057 } 3058 3059 if (mWifiNetworkSelector.isSignalTooWeak(scanResult)) { 3060 continue; 3061 } 3062 3063 // statistics to be collected ONLY for those APs with sufficient signal power 3064 3065 ssids.add(matchInfo); 3066 bssids++; 3067 boolean isOpen = matchInfo.networkType == WifiConfiguration.SECURITY_TYPE_OPEN; 3068 WifiConfiguration config = 3069 mWifiConfigManager.getConfiguredNetworkForScanDetail(scanDetail); 3070 boolean isSaved = (config != null) && !config.isEphemeral() 3071 && !config.isPasspoint(); 3072 if (isOpen) { 3073 openSsids.add(matchInfo); 3074 openBssids++; 3075 } 3076 if (isSaved) { 3077 savedSsids.add(matchInfo); 3078 savedBssids++; 3079 } 3080 if (isOpen || isSaved) { 3081 openOrSavedBssids++; 3082 // Calculate openOrSavedSsids union later 3083 } 3084 if (matchedProviders != null && !matchedProviders.isEmpty()) { 3085 for (Pair<PasspointProvider, PasspointMatch> passpointProvider : 3086 matchedProviders) { 3087 savedPasspointProviderProfiles.add(passpointProvider.first); 3088 } 3089 savedPasspointProviderBssids++; 3090 } 3091 } 3092 mWifiLogProto.fullBandAllSingleScanListenerResults++; 3093 incrementTotalScanSsids(mTotalSsidsInScanHistogram, ssids.size()); 3094 incrementTotalScanResults(mTotalBssidsInScanHistogram, bssids); 3095 incrementSsid(mAvailableOpenSsidsInScanHistogram, openSsids.size()); 3096 incrementBssid(mAvailableOpenBssidsInScanHistogram, openBssids); 3097 incrementSsid(mAvailableSavedSsidsInScanHistogram, savedSsids.size()); 3098 incrementBssid(mAvailableSavedBssidsInScanHistogram, savedBssids); 3099 openSsids.addAll(savedSsids); // openSsids = Union(openSsids, savedSsids) 3100 incrementSsid(mAvailableOpenOrSavedSsidsInScanHistogram, openSsids.size()); 3101 incrementBssid(mAvailableOpenOrSavedBssidsInScanHistogram, openOrSavedBssids); 3102 incrementSsid(mAvailableSavedPasspointProviderProfilesInScanHistogram, 3103 savedPasspointProviderProfiles.size()); 3104 incrementBssid(mAvailableSavedPasspointProviderBssidsInScanHistogram, 3105 savedPasspointProviderBssids); 3106 incrementTotalPasspointAps(mObservedHotspotR1ApInScanHistogram, passpointR1Aps); 3107 incrementTotalPasspointAps(mObservedHotspotR2ApInScanHistogram, passpointR2Aps); 3108 incrementTotalPasspointAps(mObservedHotspotR3ApInScanHistogram, passpointR3Aps); 3109 incrementTotalUniquePasspointEss(mObservedHotspotR1EssInScanHistogram, 3110 passpointR1UniqueEss.size()); 3111 incrementTotalUniquePasspointEss(mObservedHotspotR2EssInScanHistogram, 3112 passpointR2UniqueEss.size()); 3113 incrementTotalUniquePasspointEss(mObservedHotspotR3EssInScanHistogram, 3114 passpointR3UniqueEss.size()); 3115 for (Integer count : passpointR1UniqueEss.values()) { 3116 incrementPasspointPerUniqueEss(mObservedHotspotR1ApsPerEssInScanHistogram, count); 3117 } 3118 for (Integer count : passpointR2UniqueEss.values()) { 3119 incrementPasspointPerUniqueEss(mObservedHotspotR2ApsPerEssInScanHistogram, count); 3120 } 3121 for (Integer count : passpointR3UniqueEss.values()) { 3122 incrementPasspointPerUniqueEss(mObservedHotspotR3ApsPerEssInScanHistogram, count); 3123 } 3124 increment80211mcAps(mObserved80211mcApInScanHistogram, supporting80211mcAps); 3125 } 3126 } 3127 3128 /** Increments the occurence of a "Connect to Network" notification. */ incrementConnectToNetworkNotification(String notifierTag, int notificationType)3129 public void incrementConnectToNetworkNotification(String notifierTag, int notificationType) { 3130 synchronized (mLock) { 3131 int count = mConnectToNetworkNotificationCount.get(notificationType); 3132 mConnectToNetworkNotificationCount.put(notificationType, count + 1); 3133 } 3134 } 3135 3136 /** Increments the occurence of an "Connect to Network" notification user action. */ incrementConnectToNetworkNotificationAction(String notifierTag, int notificationType, int actionType)3137 public void incrementConnectToNetworkNotificationAction(String notifierTag, 3138 int notificationType, int actionType) { 3139 synchronized (mLock) { 3140 int key = notificationType * CONNECT_TO_NETWORK_NOTIFICATION_ACTION_KEY_MULTIPLIER 3141 + actionType; 3142 int count = mConnectToNetworkNotificationActionCount.get(key); 3143 mConnectToNetworkNotificationActionCount.put(key, count + 1); 3144 } 3145 } 3146 3147 /** 3148 * Sets the number of SSIDs blacklisted from recommendation by the open network notification 3149 * recommender. 3150 */ setNetworkRecommenderBlacklistSize(String notifierTag, int size)3151 public void setNetworkRecommenderBlacklistSize(String notifierTag, int size) { 3152 synchronized (mLock) { 3153 mOpenNetworkRecommenderBlacklistSize = size; 3154 } 3155 } 3156 3157 /** Sets if the available network notification feature is enabled. */ setIsWifiNetworksAvailableNotificationEnabled(String notifierTag, boolean enabled)3158 public void setIsWifiNetworksAvailableNotificationEnabled(String notifierTag, boolean enabled) { 3159 synchronized (mLock) { 3160 mIsWifiNetworksAvailableNotificationOn = enabled; 3161 } 3162 } 3163 3164 /** Increments the occurence of connection attempts that were initiated unsuccessfully */ incrementNumNetworkRecommendationUpdates(String notifierTag)3165 public void incrementNumNetworkRecommendationUpdates(String notifierTag) { 3166 synchronized (mLock) { 3167 mNumOpenNetworkRecommendationUpdates++; 3168 } 3169 } 3170 3171 /** Increments the occurence of connection attempts that were initiated unsuccessfully */ incrementNumNetworkConnectMessageFailedToSend(String notifierTag)3172 public void incrementNumNetworkConnectMessageFailedToSend(String notifierTag) { 3173 synchronized (mLock) { 3174 mNumOpenNetworkConnectMessageFailedToSend++; 3175 } 3176 } 3177 3178 /** Log firmware alert related metrics */ logFirmwareAlert(int errorCode)3179 public void logFirmwareAlert(int errorCode) { 3180 incrementAlertReasonCount(errorCode); 3181 logWifiIsUnusableEvent(WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT, errorCode); 3182 addToWifiUsabilityStatsList(WifiUsabilityStats.LABEL_BAD, 3183 WifiUsabilityStats.TYPE_FIRMWARE_ALERT, errorCode); 3184 } 3185 3186 public static final String PROTO_DUMP_ARG = "wifiMetricsProto"; 3187 public static final String CLEAN_DUMP_ARG = "clean"; 3188 3189 /** 3190 * Dump all WifiMetrics. Collects some metrics from ConfigStore, Settings and WifiManager 3191 * at this time. 3192 * 3193 * @param fd unused 3194 * @param pw PrintWriter for writing dump to 3195 * @param args [wifiMetricsProto [clean]] 3196 */ dump(FileDescriptor fd, PrintWriter pw, String[] args)3197 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 3198 synchronized (mLock) { 3199 consolidateScoringParams(); 3200 if (args != null && args.length > 0 && PROTO_DUMP_ARG.equals(args[0])) { 3201 // Dump serialized WifiLog proto 3202 consolidateProto(); 3203 3204 byte[] wifiMetricsProto = WifiMetricsProto.WifiLog.toByteArray(mWifiLogProto); 3205 String metricsProtoDump = Base64.encodeToString(wifiMetricsProto, Base64.DEFAULT); 3206 if (args.length > 1 && CLEAN_DUMP_ARG.equals(args[1])) { 3207 // Output metrics proto bytes (base64) and nothing else 3208 pw.print(metricsProtoDump); 3209 } else { 3210 // Tag the start and end of the metrics proto bytes 3211 pw.println("WifiMetrics:"); 3212 pw.println(metricsProtoDump); 3213 pw.println("EndWifiMetrics"); 3214 } 3215 clear(); 3216 } else { 3217 pw.println("WifiMetrics:"); 3218 pw.println("mConnectionEvents:"); 3219 for (ConnectionEvent event : mConnectionEventList) { 3220 String eventLine = event.toString(); 3221 if (event == mCurrentConnectionEvent) { 3222 eventLine += " CURRENTLY OPEN EVENT"; 3223 } 3224 pw.println(eventLine); 3225 } 3226 pw.println("mWifiLogProto.numSavedNetworks=" + mWifiLogProto.numSavedNetworks); 3227 pw.println("mWifiLogProto.numSavedNetworksWithMacRandomization=" 3228 + mWifiLogProto.numSavedNetworksWithMacRandomization); 3229 pw.println("mWifiLogProto.numOpenNetworks=" + mWifiLogProto.numOpenNetworks); 3230 pw.println("mWifiLogProto.numLegacyPersonalNetworks=" 3231 + mWifiLogProto.numLegacyPersonalNetworks); 3232 pw.println("mWifiLogProto.numLegacyEnterpriseNetworks=" 3233 + mWifiLogProto.numLegacyEnterpriseNetworks); 3234 pw.println("mWifiLogProto.numEnhancedOpenNetworks=" 3235 + mWifiLogProto.numEnhancedOpenNetworks); 3236 pw.println("mWifiLogProto.numWpa3PersonalNetworks=" 3237 + mWifiLogProto.numWpa3PersonalNetworks); 3238 pw.println("mWifiLogProto.numWpa3EnterpriseNetworks=" 3239 + mWifiLogProto.numWpa3EnterpriseNetworks); 3240 pw.println("mWifiLogProto.numWapiPersonalNetworks=" 3241 + mWifiLogProto.numWapiPersonalNetworks); 3242 pw.println("mWifiLogProto.numWapiEnterpriseNetworks=" 3243 + mWifiLogProto.numWapiEnterpriseNetworks); 3244 pw.println("mWifiLogProto.numHiddenNetworks=" + mWifiLogProto.numHiddenNetworks); 3245 pw.println("mWifiLogProto.numPasspointNetworks=" 3246 + mWifiLogProto.numPasspointNetworks); 3247 pw.println("mWifiLogProto.isLocationEnabled=" + mWifiLogProto.isLocationEnabled); 3248 pw.println("mWifiLogProto.isScanningAlwaysEnabled=" 3249 + mWifiLogProto.isScanningAlwaysEnabled); 3250 pw.println("mWifiLogProto.isVerboseLoggingEnabled=" 3251 + mWifiLogProto.isVerboseLoggingEnabled); 3252 pw.println("mWifiLogProto.isEnhancedMacRandomizationForceEnabled=" 3253 + mWifiLogProto.isEnhancedMacRandomizationForceEnabled); 3254 pw.println("mWifiLogProto.isWifiWakeEnabled=" + mWifiLogProto.isWifiWakeEnabled); 3255 pw.println("mWifiLogProto.numNetworksAddedByUser=" 3256 + mWifiLogProto.numNetworksAddedByUser); 3257 pw.println("mWifiLogProto.numNetworksAddedByApps=" 3258 + mWifiLogProto.numNetworksAddedByApps); 3259 pw.println("mWifiLogProto.numNonEmptyScanResults=" 3260 + mWifiLogProto.numNonEmptyScanResults); 3261 pw.println("mWifiLogProto.numEmptyScanResults=" 3262 + mWifiLogProto.numEmptyScanResults); 3263 pw.println("mWifiLogProto.numConnecitvityOneshotScans=" 3264 + mWifiLogProto.numConnectivityOneshotScans); 3265 pw.println("mWifiLogProto.numOneshotScans=" 3266 + mWifiLogProto.numOneshotScans); 3267 pw.println("mWifiLogProto.numOneshotHasDfsChannelScans=" 3268 + mWifiLogProto.numOneshotHasDfsChannelScans); 3269 pw.println("mWifiLogProto.numBackgroundScans=" 3270 + mWifiLogProto.numBackgroundScans); 3271 pw.println("mWifiLogProto.numExternalAppOneshotScanRequests=" 3272 + mWifiLogProto.numExternalAppOneshotScanRequests); 3273 pw.println("mWifiLogProto.numExternalForegroundAppOneshotScanRequestsThrottled=" 3274 + mWifiLogProto.numExternalForegroundAppOneshotScanRequestsThrottled); 3275 pw.println("mWifiLogProto.numExternalBackgroundAppOneshotScanRequestsThrottled=" 3276 + mWifiLogProto.numExternalBackgroundAppOneshotScanRequestsThrottled); 3277 pw.println("mWifiLogProto.meteredNetworkStatsSaved="); 3278 pw.println(mMeteredNetworkStatsBuilder.toProto(false)); 3279 pw.println("mWifiLogProto.meteredNetworkStatsSuggestion="); 3280 pw.println(mMeteredNetworkStatsBuilder.toProto(true)); 3281 pw.println("mScanReturnEntries:"); 3282 pw.println(" SCAN_UNKNOWN: " + getScanReturnEntry( 3283 WifiMetricsProto.WifiLog.SCAN_UNKNOWN)); 3284 pw.println(" SCAN_SUCCESS: " + getScanReturnEntry( 3285 WifiMetricsProto.WifiLog.SCAN_SUCCESS)); 3286 pw.println(" SCAN_FAILURE_INTERRUPTED: " + getScanReturnEntry( 3287 WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED)); 3288 pw.println(" SCAN_FAILURE_INVALID_CONFIGURATION: " + getScanReturnEntry( 3289 WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION)); 3290 pw.println(" FAILURE_WIFI_DISABLED: " + getScanReturnEntry( 3291 WifiMetricsProto.WifiLog.FAILURE_WIFI_DISABLED)); 3292 3293 pw.println("mSystemStateEntries: <state><screenOn> : <scansInitiated>"); 3294 pw.println(" WIFI_UNKNOWN ON: " 3295 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, true)); 3296 pw.println(" WIFI_DISABLED ON: " 3297 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISABLED, true)); 3298 pw.println(" WIFI_DISCONNECTED ON: " 3299 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED, true)); 3300 pw.println(" WIFI_ASSOCIATED ON: " 3301 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, true)); 3302 pw.println(" WIFI_UNKNOWN OFF: " 3303 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, false)); 3304 pw.println(" WIFI_DISABLED OFF: " 3305 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISABLED, false)); 3306 pw.println(" WIFI_DISCONNECTED OFF: " 3307 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED, false)); 3308 pw.println(" WIFI_ASSOCIATED OFF: " 3309 + getSystemStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, false)); 3310 pw.println("mWifiLogProto.numConnectivityWatchdogPnoGood=" 3311 + mWifiLogProto.numConnectivityWatchdogPnoGood); 3312 pw.println("mWifiLogProto.numConnectivityWatchdogPnoBad=" 3313 + mWifiLogProto.numConnectivityWatchdogPnoBad); 3314 pw.println("mWifiLogProto.numConnectivityWatchdogBackgroundGood=" 3315 + mWifiLogProto.numConnectivityWatchdogBackgroundGood); 3316 pw.println("mWifiLogProto.numConnectivityWatchdogBackgroundBad=" 3317 + mWifiLogProto.numConnectivityWatchdogBackgroundBad); 3318 pw.println("mWifiLogProto.numLastResortWatchdogTriggers=" 3319 + mWifiLogProto.numLastResortWatchdogTriggers); 3320 pw.println("mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal=" 3321 + mWifiLogProto.numLastResortWatchdogBadAssociationNetworksTotal); 3322 pw.println("mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal=" 3323 + mWifiLogProto.numLastResortWatchdogBadAuthenticationNetworksTotal); 3324 pw.println("mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal=" 3325 + mWifiLogProto.numLastResortWatchdogBadDhcpNetworksTotal); 3326 pw.println("mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal=" 3327 + mWifiLogProto.numLastResortWatchdogBadOtherNetworksTotal); 3328 pw.println("mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal=" 3329 + mWifiLogProto.numLastResortWatchdogAvailableNetworksTotal); 3330 pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation=" 3331 + mWifiLogProto.numLastResortWatchdogTriggersWithBadAssociation); 3332 pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication=" 3333 + mWifiLogProto.numLastResortWatchdogTriggersWithBadAuthentication); 3334 pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp=" 3335 + mWifiLogProto.numLastResortWatchdogTriggersWithBadDhcp); 3336 pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadOther=" 3337 + mWifiLogProto.numLastResortWatchdogTriggersWithBadOther); 3338 pw.println("mWifiLogProto.numLastResortWatchdogSuccesses=" 3339 + mWifiLogProto.numLastResortWatchdogSuccesses); 3340 pw.println("mWifiLogProto.watchdogTotalConnectionFailureCountAfterTrigger=" 3341 + mWifiLogProto.watchdogTotalConnectionFailureCountAfterTrigger); 3342 pw.println("mWifiLogProto.watchdogTriggerToConnectionSuccessDurationMs=" 3343 + mWifiLogProto.watchdogTriggerToConnectionSuccessDurationMs); 3344 pw.println("mWifiLogProto.recordDurationSec=" 3345 + ((mClock.getElapsedSinceBootMillis() / 1000) - mRecordStartTimeSec)); 3346 3347 try { 3348 JSONObject rssiMap = new JSONObject(); 3349 for (Map.Entry<Integer, SparseIntArray> entry : mRssiPollCountsMap.entrySet()) { 3350 int frequency = entry.getKey(); 3351 final SparseIntArray histogram = entry.getValue(); 3352 JSONArray histogramElements = new JSONArray(); 3353 for (int i = MIN_RSSI_POLL; i <= MAX_RSSI_POLL; i++) { 3354 int count = histogram.get(i); 3355 if (count == 0) { 3356 continue; 3357 } 3358 JSONObject histogramElement = new JSONObject(); 3359 histogramElement.put(Integer.toString(i), count); 3360 histogramElements.put(histogramElement); 3361 } 3362 rssiMap.put(Integer.toString(frequency), histogramElements); 3363 } 3364 pw.println("mWifiLogProto.rssiPollCount: " + rssiMap.toString()); 3365 } catch (JSONException e) { 3366 pw.println("JSONException occurred: " + e.getMessage()); 3367 } 3368 3369 pw.println("mWifiLogProto.rssiPollDeltaCount: Printing counts for [" 3370 + MIN_RSSI_DELTA + ", " + MAX_RSSI_DELTA + "]"); 3371 StringBuilder sb = new StringBuilder(); 3372 for (int i = MIN_RSSI_DELTA; i <= MAX_RSSI_DELTA; i++) { 3373 sb.append(mRssiDeltaCounts.get(i) + " "); 3374 } 3375 pw.println(" " + sb.toString()); 3376 pw.println("mWifiLogProto.linkSpeedCounts: "); 3377 sb.setLength(0); 3378 for (int i = 0; i < mLinkSpeedCounts.size(); i++) { 3379 LinkSpeedCount linkSpeedCount = mLinkSpeedCounts.valueAt(i); 3380 sb.append(linkSpeedCount.linkSpeedMbps).append(":{") 3381 .append(linkSpeedCount.count).append(", ") 3382 .append(linkSpeedCount.rssiSumDbm).append(", ") 3383 .append(linkSpeedCount.rssiSumOfSquaresDbmSq).append("} "); 3384 } 3385 if (sb.length() > 0) { 3386 pw.println(sb.toString()); 3387 } 3388 pw.print("mWifiLogProto.alertReasonCounts="); 3389 sb.setLength(0); 3390 for (int i = WifiLoggerHal.WIFI_ALERT_REASON_MIN; 3391 i <= WifiLoggerHal.WIFI_ALERT_REASON_MAX; i++) { 3392 int count = mWifiAlertReasonCounts.get(i); 3393 if (count > 0) { 3394 sb.append("(" + i + "," + count + "),"); 3395 } 3396 } 3397 if (sb.length() > 1) { 3398 sb.setLength(sb.length() - 1); // strip trailing comma 3399 pw.println(sb.toString()); 3400 } else { 3401 pw.println("()"); 3402 } 3403 pw.println("mWifiLogProto.numTotalScanResults=" 3404 + mWifiLogProto.numTotalScanResults); 3405 pw.println("mWifiLogProto.numOpenNetworkScanResults=" 3406 + mWifiLogProto.numOpenNetworkScanResults); 3407 pw.println("mWifiLogProto.numLegacyPersonalNetworkScanResults=" 3408 + mWifiLogProto.numLegacyPersonalNetworkScanResults); 3409 pw.println("mWifiLogProto.numLegacyEnterpriseNetworkScanResults=" 3410 + mWifiLogProto.numLegacyEnterpriseNetworkScanResults); 3411 pw.println("mWifiLogProto.numEnhancedOpenNetworkScanResults=" 3412 + mWifiLogProto.numEnhancedOpenNetworkScanResults); 3413 pw.println("mWifiLogProto.numWpa3PersonalNetworkScanResults=" 3414 + mWifiLogProto.numWpa3PersonalNetworkScanResults); 3415 pw.println("mWifiLogProto.numWpa3EnterpriseNetworkScanResults=" 3416 + mWifiLogProto.numWpa3EnterpriseNetworkScanResults); 3417 pw.println("mWifiLogProto.numWapiPersonalNetworkScanResults=" 3418 + mWifiLogProto.numWapiPersonalNetworkScanResults); 3419 pw.println("mWifiLogProto.numWapiEnterpriseNetworkScanResults=" 3420 + mWifiLogProto.numWapiEnterpriseNetworkScanResults); 3421 pw.println("mWifiLogProto.numHiddenNetworkScanResults=" 3422 + mWifiLogProto.numHiddenNetworkScanResults); 3423 pw.println("mWifiLogProto.numHotspot2R1NetworkScanResults=" 3424 + mWifiLogProto.numHotspot2R1NetworkScanResults); 3425 pw.println("mWifiLogProto.numHotspot2R2NetworkScanResults=" 3426 + mWifiLogProto.numHotspot2R2NetworkScanResults); 3427 pw.println("mWifiLogProto.numHotspot2R3NetworkScanResults=" 3428 + mWifiLogProto.numHotspot2R3NetworkScanResults); 3429 pw.println("mWifiLogProto.numMboSupportedNetworkScanResults=" 3430 + mWifiLogProto.numMboSupportedNetworkScanResults); 3431 pw.println("mWifiLogProto.numMboCellularDataAwareNetworkScanResults=" 3432 + mWifiLogProto.numMboCellularDataAwareNetworkScanResults); 3433 pw.println("mWifiLogProto.numOceSupportedNetworkScanResults=" 3434 + mWifiLogProto.numOceSupportedNetworkScanResults); 3435 pw.println("mWifiLogProto.numFilsSupportedNetworkScanResults=" 3436 + mWifiLogProto.numFilsSupportedNetworkScanResults); 3437 pw.println("mWifiLogProto.num11AxNetworkScanResults=" 3438 + mWifiLogProto.num11AxNetworkScanResults); 3439 pw.println("mWifiLogProto.num6GNetworkScanResults" 3440 + mWifiLogProto.num6GNetworkScanResults); 3441 pw.println("mWifiLogProto.numBssidFilteredDueToMboAssocDisallowInd=" 3442 + mWifiLogProto.numBssidFilteredDueToMboAssocDisallowInd); 3443 pw.println("mWifiLogProto.numConnectToNetworkSupportingMbo=" 3444 + mWifiLogProto.numConnectToNetworkSupportingMbo); 3445 pw.println("mWifiLogProto.numConnectToNetworkSupportingOce=" 3446 + mWifiLogProto.numConnectToNetworkSupportingOce); 3447 pw.println("mWifiLogProto.numForceScanDueToSteeringRequest=" 3448 + mWifiLogProto.numForceScanDueToSteeringRequest); 3449 pw.println("mWifiLogProto.numMboCellularSwitchRequest=" 3450 + mWifiLogProto.numMboCellularSwitchRequest); 3451 pw.println("mWifiLogProto.numSteeringRequestIncludingMboAssocRetryDelay=" 3452 + mWifiLogProto.numSteeringRequestIncludingMboAssocRetryDelay); 3453 pw.println("mWifiLogProto.numConnectRequestWithFilsAkm=" 3454 + mWifiLogProto.numConnectRequestWithFilsAkm); 3455 pw.println("mWifiLogProto.numL2ConnectionThroughFilsAuthentication=" 3456 + mWifiLogProto.numL2ConnectionThroughFilsAuthentication); 3457 3458 pw.println("mWifiLogProto.numScans=" + mWifiLogProto.numScans); 3459 pw.println("mWifiLogProto.WifiScoreCount: [" + MIN_WIFI_SCORE + ", " 3460 + MAX_WIFI_SCORE + "]"); 3461 for (int i = 0; i <= MAX_WIFI_SCORE; i++) { 3462 pw.print(mWifiScoreCounts.get(i) + " "); 3463 } 3464 pw.println(); // add a line after wifi scores 3465 pw.println("mWifiLogProto.WifiUsabilityScoreCount: [" + MIN_WIFI_USABILITY_SCORE 3466 + ", " + MAX_WIFI_USABILITY_SCORE + "]"); 3467 for (int i = MIN_WIFI_USABILITY_SCORE; i <= MAX_WIFI_USABILITY_SCORE; i++) { 3468 pw.print(mWifiUsabilityScoreCounts.get(i) + " "); 3469 } 3470 pw.println(); // add a line after wifi usability scores 3471 pw.println("mWifiLogProto.SoftApManagerReturnCodeCounts:"); 3472 pw.println(" SUCCESS: " + mSoftApManagerReturnCodeCounts.get( 3473 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_STARTED_SUCCESSFULLY)); 3474 pw.println(" FAILED_GENERAL_ERROR: " + mSoftApManagerReturnCodeCounts.get( 3475 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_GENERAL_ERROR)); 3476 pw.println(" FAILED_NO_CHANNEL: " + mSoftApManagerReturnCodeCounts.get( 3477 WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_NO_CHANNEL)); 3478 pw.println(" FAILED_UNSUPPORTED_CONFIGURATION: " 3479 + mSoftApManagerReturnCodeCounts.get( 3480 WifiMetricsProto.SoftApReturnCodeCount 3481 .SOFT_AP_FAILED_UNSUPPORTED_CONFIGURATION)); 3482 pw.print("\n"); 3483 pw.println("mWifiLogProto.numHalCrashes=" 3484 + mWifiLogProto.numHalCrashes); 3485 pw.println("mWifiLogProto.numWificondCrashes=" 3486 + mWifiLogProto.numWificondCrashes); 3487 pw.println("mWifiLogProto.numSupplicantCrashes=" 3488 + mWifiLogProto.numSupplicantCrashes); 3489 pw.println("mWifiLogProto.numHostapdCrashes=" 3490 + mWifiLogProto.numHostapdCrashes); 3491 pw.println("mWifiLogProto.numSetupClientInterfaceFailureDueToHal=" 3492 + mWifiLogProto.numSetupClientInterfaceFailureDueToHal); 3493 pw.println("mWifiLogProto.numSetupClientInterfaceFailureDueToWificond=" 3494 + mWifiLogProto.numSetupClientInterfaceFailureDueToWificond); 3495 pw.println("mWifiLogProto.numSetupClientInterfaceFailureDueToSupplicant=" 3496 + mWifiLogProto.numSetupClientInterfaceFailureDueToSupplicant); 3497 pw.println("mWifiLogProto.numSetupSoftApInterfaceFailureDueToHal=" 3498 + mWifiLogProto.numSetupSoftApInterfaceFailureDueToHal); 3499 pw.println("mWifiLogProto.numSetupSoftApInterfaceFailureDueToWificond=" 3500 + mWifiLogProto.numSetupSoftApInterfaceFailureDueToWificond); 3501 pw.println("mWifiLogProto.numSetupSoftApInterfaceFailureDueToHostapd=" 3502 + mWifiLogProto.numSetupSoftApInterfaceFailureDueToHostapd); 3503 pw.println("StaEventList:"); 3504 for (StaEventWithTime event : mStaEventList) { 3505 pw.println(event); 3506 } 3507 pw.println("UserActionEvents:"); 3508 for (UserActionEventWithTime event : mUserActionEventList) { 3509 pw.println(event); 3510 } 3511 3512 pw.println("mWifiLogProto.numPasspointProviders=" 3513 + mWifiLogProto.numPasspointProviders); 3514 pw.println("mWifiLogProto.numPasspointProviderInstallation=" 3515 + mWifiLogProto.numPasspointProviderInstallation); 3516 pw.println("mWifiLogProto.numPasspointProviderInstallSuccess=" 3517 + mWifiLogProto.numPasspointProviderInstallSuccess); 3518 pw.println("mWifiLogProto.numPasspointProviderUninstallation=" 3519 + mWifiLogProto.numPasspointProviderUninstallation); 3520 pw.println("mWifiLogProto.numPasspointProviderUninstallSuccess=" 3521 + mWifiLogProto.numPasspointProviderUninstallSuccess); 3522 pw.println("mWifiLogProto.numPasspointProvidersSuccessfullyConnected=" 3523 + mWifiLogProto.numPasspointProvidersSuccessfullyConnected); 3524 3525 pw.println("mWifiLogProto.installedPasspointProfileTypeForR1:" 3526 + mInstalledPasspointProfileTypeForR1); 3527 pw.println("mWifiLogProto.installedPasspointProfileTypeForR2:" 3528 + mInstalledPasspointProfileTypeForR2); 3529 3530 pw.println("mWifiLogProto.passpointProvisionStats.numProvisionSuccess=" 3531 + mNumProvisionSuccess); 3532 pw.println("mWifiLogProto.passpointProvisionStats.provisionFailureCount:" 3533 + mPasspointProvisionFailureCounts); 3534 3535 pw.println("mWifiLogProto.numRadioModeChangeToMcc=" 3536 + mWifiLogProto.numRadioModeChangeToMcc); 3537 pw.println("mWifiLogProto.numRadioModeChangeToScc=" 3538 + mWifiLogProto.numRadioModeChangeToScc); 3539 pw.println("mWifiLogProto.numRadioModeChangeToSbs=" 3540 + mWifiLogProto.numRadioModeChangeToSbs); 3541 pw.println("mWifiLogProto.numRadioModeChangeToDbs=" 3542 + mWifiLogProto.numRadioModeChangeToDbs); 3543 pw.println("mWifiLogProto.numSoftApUserBandPreferenceUnsatisfied=" 3544 + mWifiLogProto.numSoftApUserBandPreferenceUnsatisfied); 3545 pw.println("mTotalSsidsInScanHistogram:" 3546 + mTotalSsidsInScanHistogram.toString()); 3547 pw.println("mTotalBssidsInScanHistogram:" 3548 + mTotalBssidsInScanHistogram.toString()); 3549 pw.println("mAvailableOpenSsidsInScanHistogram:" 3550 + mAvailableOpenSsidsInScanHistogram.toString()); 3551 pw.println("mAvailableOpenBssidsInScanHistogram:" 3552 + mAvailableOpenBssidsInScanHistogram.toString()); 3553 pw.println("mAvailableSavedSsidsInScanHistogram:" 3554 + mAvailableSavedSsidsInScanHistogram.toString()); 3555 pw.println("mAvailableSavedBssidsInScanHistogram:" 3556 + mAvailableSavedBssidsInScanHistogram.toString()); 3557 pw.println("mAvailableOpenOrSavedSsidsInScanHistogram:" 3558 + mAvailableOpenOrSavedSsidsInScanHistogram.toString()); 3559 pw.println("mAvailableOpenOrSavedBssidsInScanHistogram:" 3560 + mAvailableOpenOrSavedBssidsInScanHistogram.toString()); 3561 pw.println("mAvailableSavedPasspointProviderProfilesInScanHistogram:" 3562 + mAvailableSavedPasspointProviderProfilesInScanHistogram.toString()); 3563 pw.println("mAvailableSavedPasspointProviderBssidsInScanHistogram:" 3564 + mAvailableSavedPasspointProviderBssidsInScanHistogram.toString()); 3565 pw.println("mWifiLogProto.partialAllSingleScanListenerResults=" 3566 + mWifiLogProto.partialAllSingleScanListenerResults); 3567 pw.println("mWifiLogProto.fullBandAllSingleScanListenerResults=" 3568 + mWifiLogProto.fullBandAllSingleScanListenerResults); 3569 pw.println("mWifiAwareMetrics:"); 3570 mWifiAwareMetrics.dump(fd, pw, args); 3571 pw.println("mRttMetrics:"); 3572 mRttMetrics.dump(fd, pw, args); 3573 3574 pw.println("mPnoScanMetrics.numPnoScanAttempts=" 3575 + mPnoScanMetrics.numPnoScanAttempts); 3576 pw.println("mPnoScanMetrics.numPnoScanFailed=" 3577 + mPnoScanMetrics.numPnoScanFailed); 3578 pw.println("mPnoScanMetrics.numPnoScanStartedOverOffload=" 3579 + mPnoScanMetrics.numPnoScanStartedOverOffload); 3580 pw.println("mPnoScanMetrics.numPnoScanFailedOverOffload=" 3581 + mPnoScanMetrics.numPnoScanFailedOverOffload); 3582 pw.println("mPnoScanMetrics.numPnoFoundNetworkEvents=" 3583 + mPnoScanMetrics.numPnoFoundNetworkEvents); 3584 3585 pw.println("mWifiLinkLayerUsageStats.loggingDurationMs=" 3586 + mWifiLinkLayerUsageStats.loggingDurationMs); 3587 pw.println("mWifiLinkLayerUsageStats.radioOnTimeMs=" 3588 + mWifiLinkLayerUsageStats.radioOnTimeMs); 3589 pw.println("mWifiLinkLayerUsageStats.radioTxTimeMs=" 3590 + mWifiLinkLayerUsageStats.radioTxTimeMs); 3591 pw.println("mWifiLinkLayerUsageStats.radioRxTimeMs=" 3592 + mWifiLinkLayerUsageStats.radioRxTimeMs); 3593 pw.println("mWifiLinkLayerUsageStats.radioScanTimeMs=" 3594 + mWifiLinkLayerUsageStats.radioScanTimeMs); 3595 pw.println("mWifiLinkLayerUsageStats.radioNanScanTimeMs=" 3596 + mWifiLinkLayerUsageStats.radioNanScanTimeMs); 3597 pw.println("mWifiLinkLayerUsageStats.radioBackgroundScanTimeMs=" 3598 + mWifiLinkLayerUsageStats.radioBackgroundScanTimeMs); 3599 pw.println("mWifiLinkLayerUsageStats.radioRoamScanTimeMs=" 3600 + mWifiLinkLayerUsageStats.radioRoamScanTimeMs); 3601 pw.println("mWifiLinkLayerUsageStats.radioPnoScanTimeMs=" 3602 + mWifiLinkLayerUsageStats.radioPnoScanTimeMs); 3603 pw.println("mWifiLinkLayerUsageStats.radioHs20ScanTimeMs=" 3604 + mWifiLinkLayerUsageStats.radioHs20ScanTimeMs); 3605 3606 pw.println("mWifiLogProto.connectToNetworkNotificationCount=" 3607 + mConnectToNetworkNotificationCount.toString()); 3608 pw.println("mWifiLogProto.connectToNetworkNotificationActionCount=" 3609 + mConnectToNetworkNotificationActionCount.toString()); 3610 pw.println("mWifiLogProto.openNetworkRecommenderBlacklistSize=" 3611 + mOpenNetworkRecommenderBlacklistSize); 3612 pw.println("mWifiLogProto.isWifiNetworksAvailableNotificationOn=" 3613 + mIsWifiNetworksAvailableNotificationOn); 3614 pw.println("mWifiLogProto.numOpenNetworkRecommendationUpdates=" 3615 + mNumOpenNetworkRecommendationUpdates); 3616 pw.println("mWifiLogProto.numOpenNetworkConnectMessageFailedToSend=" 3617 + mNumOpenNetworkConnectMessageFailedToSend); 3618 3619 pw.println("mWifiLogProto.observedHotspotR1ApInScanHistogram=" 3620 + mObservedHotspotR1ApInScanHistogram); 3621 pw.println("mWifiLogProto.observedHotspotR2ApInScanHistogram=" 3622 + mObservedHotspotR2ApInScanHistogram); 3623 pw.println("mWifiLogProto.observedHotspotR3ApInScanHistogram=" 3624 + mObservedHotspotR3ApInScanHistogram); 3625 pw.println("mWifiLogProto.observedHotspotR1EssInScanHistogram=" 3626 + mObservedHotspotR1EssInScanHistogram); 3627 pw.println("mWifiLogProto.observedHotspotR2EssInScanHistogram=" 3628 + mObservedHotspotR2EssInScanHistogram); 3629 pw.println("mWifiLogProto.observedHotspotR3EssInScanHistogram=" 3630 + mObservedHotspotR3EssInScanHistogram); 3631 pw.println("mWifiLogProto.observedHotspotR1ApsPerEssInScanHistogram=" 3632 + mObservedHotspotR1ApsPerEssInScanHistogram); 3633 pw.println("mWifiLogProto.observedHotspotR2ApsPerEssInScanHistogram=" 3634 + mObservedHotspotR2ApsPerEssInScanHistogram); 3635 pw.println("mWifiLogProto.observedHotspotR3ApsPerEssInScanHistogram=" 3636 + mObservedHotspotR3ApsPerEssInScanHistogram); 3637 3638 pw.println("mWifiLogProto.observed80211mcSupportingApsInScanHistogram" 3639 + mObserved80211mcApInScanHistogram); 3640 pw.println("mWifiLogProto.bssidBlocklistStats:"); 3641 pw.println(mBssidBlocklistStats.toString()); 3642 3643 pw.println("mSoftApTetheredEvents:"); 3644 for (SoftApConnectedClientsEvent event : mSoftApEventListTethered) { 3645 StringBuilder eventLine = new StringBuilder(); 3646 eventLine.append("event_type=" + event.eventType); 3647 eventLine.append(",time_stamp_millis=" + event.timeStampMillis); 3648 eventLine.append(",num_connected_clients=" + event.numConnectedClients); 3649 eventLine.append(",channel_frequency=" + event.channelFrequency); 3650 eventLine.append(",channel_bandwidth=" + event.channelBandwidth); 3651 eventLine.append(",max_num_clients_setting_in_softap_configuration=" 3652 + event.maxNumClientsSettingInSoftapConfiguration); 3653 eventLine.append(",max_num_clients_setting_in_softap_capability=" 3654 + event.maxNumClientsSettingInSoftapCapability); 3655 eventLine.append(",shutdown_timeout_setting_in_softap_configuration=" 3656 + event.shutdownTimeoutSettingInSoftapConfiguration); 3657 eventLine.append(",default_shutdown_timeout_setting=" 3658 + event.defaultShutdownTimeoutSetting); 3659 eventLine.append(",client_control_is_enabled=" + event.clientControlIsEnabled); 3660 pw.println(eventLine.toString()); 3661 } 3662 pw.println("mSoftApLocalOnlyEvents:"); 3663 for (SoftApConnectedClientsEvent event : mSoftApEventListLocalOnly) { 3664 StringBuilder eventLine = new StringBuilder(); 3665 eventLine.append("event_type=" + event.eventType); 3666 eventLine.append(",time_stamp_millis=" + event.timeStampMillis); 3667 eventLine.append(",num_connected_clients=" + event.numConnectedClients); 3668 eventLine.append(",channel_frequency=" + event.channelFrequency); 3669 eventLine.append(",channel_bandwidth=" + event.channelBandwidth); 3670 eventLine.append(",max_num_clients_setting_in_softap_configuration=" 3671 + event.maxNumClientsSettingInSoftapConfiguration); 3672 eventLine.append(",max_num_clients_setting_in_softap_capability=" 3673 + event.maxNumClientsSettingInSoftapCapability); 3674 eventLine.append(",shutdown_timeout_setting_in_softap_configuration=" 3675 + event.shutdownTimeoutSettingInSoftapConfiguration); 3676 eventLine.append(",default_shutdown_timeout_setting=" 3677 + event.defaultShutdownTimeoutSetting); 3678 eventLine.append(",client_control_is_enabled=" + event.clientControlIsEnabled); 3679 pw.println(eventLine.toString()); 3680 } 3681 3682 mWifiPowerMetrics.dump(pw); 3683 mWifiWakeMetrics.dump(pw); 3684 3685 pw.println("mWifiLogProto.isMacRandomizationOn=" 3686 + mContext.getResources().getBoolean( 3687 R.bool.config_wifi_connected_mac_randomization_supported)); 3688 pw.println("mWifiLogProto.scoreExperimentId=" + mWifiLogProto.scoreExperimentId); 3689 pw.println("mExperimentValues.wifiIsUnusableLoggingEnabled=" 3690 + mContext.getResources().getBoolean( 3691 R.bool.config_wifiIsUnusableEventMetricsEnabled)); 3692 pw.println("mExperimentValues.wifiDataStallMinTxBad=" 3693 + mContext.getResources().getInteger( 3694 R.integer.config_wifiDataStallMinTxBad)); 3695 pw.println("mExperimentValues.wifiDataStallMinTxSuccessWithoutRx=" 3696 + mContext.getResources().getInteger( 3697 R.integer.config_wifiDataStallMinTxSuccessWithoutRx)); 3698 pw.println("mExperimentValues.linkSpeedCountsLoggingEnabled=" 3699 + mContext.getResources().getBoolean( 3700 R.bool.config_wifiLinkSpeedMetricsEnabled)); 3701 pw.println("mExperimentValues.dataStallDurationMs=" 3702 + mExperimentValues.dataStallDurationMs); 3703 pw.println("mExperimentValues.dataStallTxTputThrKbps=" 3704 + mExperimentValues.dataStallTxTputThrKbps); 3705 pw.println("mExperimentValues.dataStallRxTputThrKbps=" 3706 + mExperimentValues.dataStallRxTputThrKbps); 3707 pw.println("mExperimentValues.dataStallTxPerThr=" 3708 + mExperimentValues.dataStallTxPerThr); 3709 pw.println("mExperimentValues.dataStallCcaLevelThr=" 3710 + mExperimentValues.dataStallCcaLevelThr); 3711 pw.println("WifiIsUnusableEventList: "); 3712 for (WifiIsUnusableWithTime event : mWifiIsUnusableList) { 3713 pw.println(event); 3714 } 3715 pw.println("Hardware Version: " + SystemProperties.get("ro.boot.revision", "")); 3716 3717 pw.println("mWifiUsabilityStatsEntriesList:"); 3718 for (WifiUsabilityStatsEntry stats : mWifiUsabilityStatsEntriesList) { 3719 printWifiUsabilityStatsEntry(pw, stats); 3720 } 3721 pw.println("mWifiUsabilityStatsList:"); 3722 for (WifiUsabilityStats stats : mWifiUsabilityStatsListGood) { 3723 pw.println("\nlabel=" + stats.label); 3724 pw.println("\ntrigger_type=" + stats.triggerType); 3725 pw.println("\ntime_stamp_ms=" + stats.timeStampMs); 3726 for (WifiUsabilityStatsEntry entry : stats.stats) { 3727 printWifiUsabilityStatsEntry(pw, entry); 3728 } 3729 } 3730 for (WifiUsabilityStats stats : mWifiUsabilityStatsListBad) { 3731 pw.println("\nlabel=" + stats.label); 3732 pw.println("\ntrigger_type=" + stats.triggerType); 3733 pw.println("\ntime_stamp_ms=" + stats.timeStampMs); 3734 for (WifiUsabilityStatsEntry entry : stats.stats) { 3735 printWifiUsabilityStatsEntry(pw, entry); 3736 } 3737 } 3738 3739 pw.println("mMobilityStatePnoStatsMap:"); 3740 for (int i = 0; i < mMobilityStatePnoStatsMap.size(); i++) { 3741 printDeviceMobilityStatePnoScanStats(pw, mMobilityStatePnoStatsMap.valueAt(i)); 3742 } 3743 3744 mWifiP2pMetrics.dump(pw); 3745 pw.println("mDppMetrics:"); 3746 mDppMetrics.dump(pw); 3747 3748 pw.println("mWifiConfigStoreReadDurationHistogram:" 3749 + mWifiConfigStoreReadDurationHistogram.toString()); 3750 pw.println("mWifiConfigStoreWriteDurationHistogram:" 3751 + mWifiConfigStoreWriteDurationHistogram.toString()); 3752 3753 pw.println("mLinkProbeSuccessRssiCounts:" + mLinkProbeSuccessRssiCounts); 3754 pw.println("mLinkProbeFailureRssiCounts:" + mLinkProbeFailureRssiCounts); 3755 pw.println("mLinkProbeSuccessLinkSpeedCounts:" + mLinkProbeSuccessLinkSpeedCounts); 3756 pw.println("mLinkProbeFailureLinkSpeedCounts:" + mLinkProbeFailureLinkSpeedCounts); 3757 pw.println("mLinkProbeSuccessSecondsSinceLastTxSuccessHistogram:" 3758 + mLinkProbeSuccessSecondsSinceLastTxSuccessHistogram); 3759 pw.println("mLinkProbeFailureSecondsSinceLastTxSuccessHistogram:" 3760 + mLinkProbeFailureSecondsSinceLastTxSuccessHistogram); 3761 pw.println("mLinkProbeSuccessElapsedTimeMsHistogram:" 3762 + mLinkProbeSuccessElapsedTimeMsHistogram); 3763 pw.println("mLinkProbeFailureReasonCounts:" + mLinkProbeFailureReasonCounts); 3764 pw.println("mLinkProbeExperimentProbeCounts:" + mLinkProbeExperimentProbeCounts); 3765 3766 pw.println("mNetworkSelectionExperimentPairNumChoicesCounts:" 3767 + mNetworkSelectionExperimentPairNumChoicesCounts); 3768 pw.println("mLinkProbeStaEventCount:" + mLinkProbeStaEventCount); 3769 3770 pw.println("mWifiNetworkRequestApiLog:\n" + mWifiNetworkRequestApiLog); 3771 pw.println("mWifiNetworkRequestApiMatchSizeHistogram:\n" 3772 + mWifiNetworkRequestApiMatchSizeHistogram); 3773 pw.println("mWifiNetworkSuggestionApiLog:\n" + mWifiNetworkSuggestionApiLog); 3774 pw.println("mWifiNetworkSuggestionApiMatchSizeHistogram:\n" 3775 + mWifiNetworkSuggestionApiListSizeHistogram); 3776 pw.println("mWifiNetworkSuggestionApiAppTypeCounter:\n" 3777 + mWifiNetworkSuggestionApiAppTypeCounter); 3778 printUserApprovalSuggestionAppReaction(pw); 3779 printUserApprovalCarrierReaction(pw); 3780 pw.println("mNetworkIdToNominatorId:\n" + mNetworkIdToNominatorId); 3781 pw.println("mWifiLockStats:\n" + mWifiLockStats); 3782 pw.println("mWifiLockHighPerfAcqDurationSecHistogram:\n" 3783 + mWifiLockHighPerfAcqDurationSecHistogram); 3784 pw.println("mWifiLockLowLatencyAcqDurationSecHistogram:\n" 3785 + mWifiLockLowLatencyAcqDurationSecHistogram); 3786 pw.println("mWifiLockHighPerfActiveSessionDurationSecHistogram:\n" 3787 + mWifiLockHighPerfActiveSessionDurationSecHistogram); 3788 pw.println("mWifiLockLowLatencyActiveSessionDurationSecHistogram:\n" 3789 + mWifiLockLowLatencyActiveSessionDurationSecHistogram); 3790 pw.println("mWifiToggleStats:\n" + mWifiToggleStats); 3791 pw.println("mWifiLogProto.numAddOrUpdateNetworkCalls=" 3792 + mWifiLogProto.numAddOrUpdateNetworkCalls); 3793 pw.println("mWifiLogProto.numEnableNetworkCalls=" 3794 + mWifiLogProto.numEnableNetworkCalls); 3795 3796 pw.println("mWifiLogProto.txLinkSpeedCount2g=" + mTxLinkSpeedCount2g); 3797 pw.println("mWifiLogProto.txLinkSpeedCount5gLow=" + mTxLinkSpeedCount5gLow); 3798 pw.println("mWifiLogProto.txLinkSpeedCount5gMid=" + mTxLinkSpeedCount5gMid); 3799 pw.println("mWifiLogProto.txLinkSpeedCount5gHigh=" + mTxLinkSpeedCount5gHigh); 3800 pw.println("mWifiLogProto.txLinkSpeedCount6gLow=" + mTxLinkSpeedCount6gLow); 3801 pw.println("mWifiLogProto.txLinkSpeedCount6gMid=" + mTxLinkSpeedCount6gMid); 3802 pw.println("mWifiLogProto.txLinkSpeedCount6gHigh=" + mTxLinkSpeedCount6gHigh); 3803 3804 pw.println("mWifiLogProto.rxLinkSpeedCount2g=" + mRxLinkSpeedCount2g); 3805 pw.println("mWifiLogProto.rxLinkSpeedCount5gLow=" + mRxLinkSpeedCount5gLow); 3806 pw.println("mWifiLogProto.rxLinkSpeedCount5gMid=" + mRxLinkSpeedCount5gMid); 3807 pw.println("mWifiLogProto.rxLinkSpeedCount5gHigh=" + mRxLinkSpeedCount5gHigh); 3808 pw.println("mWifiLogProto.rxLinkSpeedCount6gLow=" + mRxLinkSpeedCount6gLow); 3809 pw.println("mWifiLogProto.rxLinkSpeedCount6gMid=" + mRxLinkSpeedCount6gMid); 3810 pw.println("mWifiLogProto.rxLinkSpeedCount6gHigh=" + mRxLinkSpeedCount6gHigh); 3811 3812 pw.println("mWifiLogProto.numIpRenewalFailure=" 3813 + mWifiLogProto.numIpRenewalFailure); 3814 pw.println("mWifiLogProto.connectionDurationStats=" 3815 + mConnectionDurationStats.toString()); 3816 pw.println("mWifiLogProto.isExternalWifiScorerOn=" 3817 + mWifiLogProto.isExternalWifiScorerOn); 3818 pw.println("mWifiLogProto.wifiOffMetrics=" 3819 + mWifiOffMetrics.toString()); 3820 pw.println("mWifiLogProto.softApConfigLimitationMetrics=" 3821 + mSoftApConfigLimitationMetrics.toString()); 3822 pw.println("mChannelUtilizationHistogram2G:\n" 3823 + mChannelUtilizationHistogram2G); 3824 pw.println("mChannelUtilizationHistogramAbove2G:\n" 3825 + mChannelUtilizationHistogramAbove2G); 3826 pw.println("mTxThroughputMbpsHistogram2G:\n" 3827 + mTxThroughputMbpsHistogram2G); 3828 pw.println("mRxThroughputMbpsHistogram2G:\n" 3829 + mRxThroughputMbpsHistogram2G); 3830 pw.println("mTxThroughputMbpsHistogramAbove2G:\n" 3831 + mTxThroughputMbpsHistogramAbove2G); 3832 pw.println("mRxThroughputMbpsHistogramAbove2G:\n" 3833 + mRxThroughputMbpsHistogramAbove2G); 3834 pw.println("mCarrierWifiMetrics:\n" 3835 + mCarrierWifiMetrics); 3836 3837 dumpInitPartialScanMetrics(pw); 3838 } 3839 } 3840 } 3841 dumpInitPartialScanMetrics(PrintWriter pw)3842 private void dumpInitPartialScanMetrics(PrintWriter pw) { 3843 pw.println("mInitPartialScanTotalCount:\n" + mInitPartialScanTotalCount); 3844 pw.println("mInitPartialScanSuccessCount:\n" + mInitPartialScanSuccessCount); 3845 pw.println("mInitPartialScanFailureCount:\n" + mInitPartialScanFailureCount); 3846 pw.println("mInitPartialScanSuccessHistogram:\n" + mInitPartialScanSuccessHistogram); 3847 pw.println("mInitPartialScanFailureHistogram:\n" + mInitPartialScanFailureHistogram); 3848 } 3849 printWifiUsabilityStatsEntry(PrintWriter pw, WifiUsabilityStatsEntry entry)3850 private void printWifiUsabilityStatsEntry(PrintWriter pw, WifiUsabilityStatsEntry entry) { 3851 StringBuilder line = new StringBuilder(); 3852 line.append("timestamp_ms=" + entry.timeStampMs); 3853 line.append(",rssi=" + entry.rssi); 3854 line.append(",link_speed_mbps=" + entry.linkSpeedMbps); 3855 line.append(",total_tx_success=" + entry.totalTxSuccess); 3856 line.append(",total_tx_retries=" + entry.totalTxRetries); 3857 line.append(",total_tx_bad=" + entry.totalTxBad); 3858 line.append(",total_rx_success=" + entry.totalRxSuccess); 3859 line.append(",total_radio_on_time_ms=" + entry.totalRadioOnTimeMs); 3860 line.append(",total_radio_tx_time_ms=" + entry.totalRadioTxTimeMs); 3861 line.append(",total_radio_rx_time_ms=" + entry.totalRadioRxTimeMs); 3862 line.append(",total_scan_time_ms=" + entry.totalScanTimeMs); 3863 line.append(",total_nan_scan_time_ms=" + entry.totalNanScanTimeMs); 3864 line.append(",total_background_scan_time_ms=" + entry.totalBackgroundScanTimeMs); 3865 line.append(",total_roam_scan_time_ms=" + entry.totalRoamScanTimeMs); 3866 line.append(",total_pno_scan_time_ms=" + entry.totalPnoScanTimeMs); 3867 line.append(",total_hotspot_2_scan_time_ms=" + entry.totalHotspot2ScanTimeMs); 3868 line.append(",wifi_score=" + entry.wifiScore); 3869 line.append(",wifi_usability_score=" + entry.wifiUsabilityScore); 3870 line.append(",seq_num_to_framework=" + entry.seqNumToFramework); 3871 line.append(",prediction_horizon_sec=" + entry.predictionHorizonSec); 3872 line.append(",total_cca_busy_freq_time_ms=" + entry.totalCcaBusyFreqTimeMs); 3873 line.append(",total_radio_on_freq_time_ms=" + entry.totalRadioOnFreqTimeMs); 3874 line.append(",total_beacon_rx=" + entry.totalBeaconRx); 3875 line.append(",probe_status_since_last_update=" + entry.probeStatusSinceLastUpdate); 3876 line.append(",probe_elapsed_time_ms_since_last_update=" 3877 + entry.probeElapsedTimeSinceLastUpdateMs); 3878 line.append(",probe_mcs_rate_since_last_update=" + entry.probeMcsRateSinceLastUpdate); 3879 line.append(",rx_link_speed_mbps=" + entry.rxLinkSpeedMbps); 3880 line.append(",seq_num_inside_framework=" + entry.seqNumInsideFramework); 3881 line.append(",is_same_bssid_and_freq=" + entry.isSameBssidAndFreq); 3882 line.append(",device_mobility_state=" + entry.deviceMobilityState); 3883 pw.println(line.toString()); 3884 } 3885 printDeviceMobilityStatePnoScanStats(PrintWriter pw, DeviceMobilityStatePnoScanStats stats)3886 private void printDeviceMobilityStatePnoScanStats(PrintWriter pw, 3887 DeviceMobilityStatePnoScanStats stats) { 3888 StringBuilder line = new StringBuilder(); 3889 line.append("device_mobility_state=" + stats.deviceMobilityState); 3890 line.append(",num_times_entered_state=" + stats.numTimesEnteredState); 3891 line.append(",total_duration_ms=" + stats.totalDurationMs); 3892 line.append(",pno_duration_ms=" + stats.pnoDurationMs); 3893 pw.println(line.toString()); 3894 } 3895 printUserApprovalSuggestionAppReaction(PrintWriter pw)3896 private void printUserApprovalSuggestionAppReaction(PrintWriter pw) { 3897 pw.println("mUserApprovalSuggestionAppUiUserReaction:"); 3898 for (UserReaction event : mUserApprovalSuggestionAppUiReactionList) { 3899 pw.println(event); 3900 } 3901 } 3902 printUserApprovalCarrierReaction(PrintWriter pw)3903 private void printUserApprovalCarrierReaction(PrintWriter pw) { 3904 pw.println("mUserApprovalCarrierUiUserReaction:"); 3905 for (UserReaction event : mUserApprovalCarrierUiReactionList) { 3906 pw.println(event); 3907 } 3908 } 3909 3910 /** 3911 * Update various counts of saved network types 3912 * @param networks List of WifiConfigurations representing all saved networks, must not be null 3913 */ updateSavedNetworks(List<WifiConfiguration> networks)3914 public void updateSavedNetworks(List<WifiConfiguration> networks) { 3915 synchronized (mLock) { 3916 mWifiLogProto.numSavedNetworks = networks.size(); 3917 mWifiLogProto.numSavedNetworksWithMacRandomization = 0; 3918 mWifiLogProto.numOpenNetworks = 0; 3919 mWifiLogProto.numLegacyPersonalNetworks = 0; 3920 mWifiLogProto.numLegacyEnterpriseNetworks = 0; 3921 mWifiLogProto.numEnhancedOpenNetworks = 0; 3922 mWifiLogProto.numWpa3PersonalNetworks = 0; 3923 mWifiLogProto.numWpa3EnterpriseNetworks = 0; 3924 mWifiLogProto.numWapiPersonalNetworks = 0; 3925 mWifiLogProto.numWapiEnterpriseNetworks = 0; 3926 mWifiLogProto.numNetworksAddedByUser = 0; 3927 mWifiLogProto.numNetworksAddedByApps = 0; 3928 mWifiLogProto.numHiddenNetworks = 0; 3929 mWifiLogProto.numPasspointNetworks = 0; 3930 3931 for (WifiConfiguration config : networks) { 3932 if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) { 3933 mWifiLogProto.numOpenNetworks++; 3934 } else if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE)) { 3935 mWifiLogProto.numEnhancedOpenNetworks++; 3936 } else if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WAPI_PSK)) { 3937 mWifiLogProto.numWapiPersonalNetworks++; 3938 } else if (config.isEnterprise()) { 3939 if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SUITE_B_192)) { 3940 mWifiLogProto.numWpa3EnterpriseNetworks++; 3941 } else if (config.allowedKeyManagement.get( 3942 WifiConfiguration.KeyMgmt.WAPI_CERT)) { 3943 mWifiLogProto.numWapiEnterpriseNetworks++; 3944 } else { 3945 mWifiLogProto.numLegacyEnterpriseNetworks++; 3946 } 3947 } else { 3948 if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) { 3949 mWifiLogProto.numWpa3PersonalNetworks++; 3950 } else { 3951 mWifiLogProto.numLegacyPersonalNetworks++; 3952 } 3953 } 3954 mWifiLogProto.numNetworksAddedByApps++; 3955 if (config.hiddenSSID) { 3956 mWifiLogProto.numHiddenNetworks++; 3957 } 3958 if (config.isPasspoint()) { 3959 mWifiLogProto.numPasspointNetworks++; 3960 } 3961 if (config.macRandomizationSetting == WifiConfiguration.RANDOMIZATION_PERSISTENT) { 3962 mWifiLogProto.numSavedNetworksWithMacRandomization++; 3963 } 3964 } 3965 } 3966 } 3967 3968 /** 3969 * Update metrics for saved Passpoint profiles. 3970 * 3971 * @param numSavedProfiles The number of saved Passpoint profiles 3972 * @param numConnectedProfiles The number of saved Passpoint profiles that have ever resulted 3973 * in a successful network connection 3974 */ updateSavedPasspointProfiles(int numSavedProfiles, int numConnectedProfiles)3975 public void updateSavedPasspointProfiles(int numSavedProfiles, int numConnectedProfiles) { 3976 synchronized (mLock) { 3977 mWifiLogProto.numPasspointProviders = numSavedProfiles; 3978 mWifiLogProto.numPasspointProvidersSuccessfullyConnected = numConnectedProfiles; 3979 } 3980 } 3981 3982 /** 3983 * Update number of times for type of saved Passpoint profile. 3984 * 3985 * @param providers Passpoint providers installed on the device. 3986 */ updateSavedPasspointProfilesInfo( Map<String, PasspointProvider> providers)3987 public void updateSavedPasspointProfilesInfo( 3988 Map<String, PasspointProvider> providers) { 3989 int passpointType; 3990 int eapType; 3991 PasspointConfiguration config; 3992 synchronized (mLock) { 3993 mInstalledPasspointProfileTypeForR1.clear(); 3994 mInstalledPasspointProfileTypeForR2.clear(); 3995 for (Map.Entry<String, PasspointProvider> entry : providers.entrySet()) { 3996 config = entry.getValue().getConfig(); 3997 if (config.getCredential().getUserCredential() != null) { 3998 eapType = EAPConstants.EAP_TTLS; 3999 } else if (config.getCredential().getCertCredential() != null) { 4000 eapType = EAPConstants.EAP_TLS; 4001 } else if (config.getCredential().getSimCredential() != null) { 4002 eapType = config.getCredential().getSimCredential().getEapType(); 4003 } else { 4004 eapType = -1; 4005 } 4006 switch (eapType) { 4007 case EAPConstants.EAP_TLS: 4008 passpointType = WifiMetricsProto.PasspointProfileTypeCount.TYPE_EAP_TLS; 4009 break; 4010 case EAPConstants.EAP_TTLS: 4011 passpointType = WifiMetricsProto.PasspointProfileTypeCount.TYPE_EAP_TTLS; 4012 break; 4013 case EAPConstants.EAP_SIM: 4014 passpointType = WifiMetricsProto.PasspointProfileTypeCount.TYPE_EAP_SIM; 4015 break; 4016 case EAPConstants.EAP_AKA: 4017 passpointType = WifiMetricsProto.PasspointProfileTypeCount.TYPE_EAP_AKA; 4018 break; 4019 case EAPConstants.EAP_AKA_PRIME: 4020 passpointType = 4021 WifiMetricsProto.PasspointProfileTypeCount.TYPE_EAP_AKA_PRIME; 4022 break; 4023 default: 4024 passpointType = WifiMetricsProto.PasspointProfileTypeCount.TYPE_UNKNOWN; 4025 4026 } 4027 if (config.validateForR2()) { 4028 mInstalledPasspointProfileTypeForR2.increment(passpointType); 4029 } else { 4030 mInstalledPasspointProfileTypeForR1.increment(passpointType); 4031 } 4032 } 4033 } 4034 } 4035 4036 /** 4037 * Increment initial partial scan count 4038 */ incrementInitialPartialScanCount()4039 public void incrementInitialPartialScanCount() { 4040 synchronized (mLock) { 4041 mInitPartialScanTotalCount++; 4042 } 4043 } 4044 4045 /** 4046 * Report of initial partial scan 4047 * @param channelCount number of channels used in this scan 4048 * @param status true if scan resulted in a network connection attempt, false otherwise 4049 */ reportInitialPartialScan(int channelCount, boolean status)4050 public void reportInitialPartialScan(int channelCount, boolean status) { 4051 synchronized (mLock) { 4052 if (status) { 4053 mInitPartialScanSuccessCount++; 4054 mInitPartialScanSuccessHistogram.increment(channelCount); 4055 } else { 4056 mInitPartialScanFailureCount++; 4057 mInitPartialScanFailureHistogram.increment(channelCount); 4058 } 4059 } 4060 } 4061 4062 /** 4063 * Put all metrics that were being tracked separately into mWifiLogProto 4064 */ consolidateProto()4065 private void consolidateProto() { 4066 List<WifiMetricsProto.RssiPollCount> rssis = new ArrayList<>(); 4067 synchronized (mLock) { 4068 int connectionEventCount = mConnectionEventList.size(); 4069 // Exclude the current active un-ended connection event 4070 if (mCurrentConnectionEvent != null) { 4071 connectionEventCount--; 4072 } 4073 mWifiLogProto.connectionEvent = 4074 new WifiMetricsProto.ConnectionEvent[connectionEventCount]; 4075 for (int i = 0; i < connectionEventCount; i++) { 4076 mWifiLogProto.connectionEvent[i] = mConnectionEventList.get(i).mConnectionEvent; 4077 } 4078 4079 //Convert the SparseIntArray of scanReturnEntry integers into ScanReturnEntry proto list 4080 mWifiLogProto.scanReturnEntries = 4081 new WifiMetricsProto.WifiLog.ScanReturnEntry[mScanReturnEntries.size()]; 4082 for (int i = 0; i < mScanReturnEntries.size(); i++) { 4083 mWifiLogProto.scanReturnEntries[i] = new WifiMetricsProto.WifiLog.ScanReturnEntry(); 4084 mWifiLogProto.scanReturnEntries[i].scanReturnCode = mScanReturnEntries.keyAt(i); 4085 mWifiLogProto.scanReturnEntries[i].scanResultsCount = mScanReturnEntries.valueAt(i); 4086 } 4087 4088 // Convert the SparseIntArray of systemStateEntry into WifiSystemStateEntry proto list 4089 // This one is slightly more complex, as the Sparse are indexed with: 4090 // key: wifiState * 2 + isScreenOn, value: wifiStateCount 4091 mWifiLogProto.wifiSystemStateEntries = 4092 new WifiMetricsProto.WifiLog 4093 .WifiSystemStateEntry[mWifiSystemStateEntries.size()]; 4094 for (int i = 0; i < mWifiSystemStateEntries.size(); i++) { 4095 mWifiLogProto.wifiSystemStateEntries[i] = 4096 new WifiMetricsProto.WifiLog.WifiSystemStateEntry(); 4097 mWifiLogProto.wifiSystemStateEntries[i].wifiState = 4098 mWifiSystemStateEntries.keyAt(i) / 2; 4099 mWifiLogProto.wifiSystemStateEntries[i].wifiStateCount = 4100 mWifiSystemStateEntries.valueAt(i); 4101 mWifiLogProto.wifiSystemStateEntries[i].isScreenOn = 4102 (mWifiSystemStateEntries.keyAt(i) % 2) > 0; 4103 } 4104 mWifiLogProto.recordDurationSec = (int) ((mClock.getElapsedSinceBootMillis() / 1000) 4105 - mRecordStartTimeSec); 4106 4107 /** 4108 * Convert the SparseIntArrays of RSSI poll rssi, counts, and frequency to the 4109 * proto's repeated IntKeyVal array. 4110 */ 4111 for (Map.Entry<Integer, SparseIntArray> entry : mRssiPollCountsMap.entrySet()) { 4112 int frequency = entry.getKey(); 4113 SparseIntArray histogram = entry.getValue(); 4114 for (int i = 0; i < histogram.size(); i++) { 4115 WifiMetricsProto.RssiPollCount keyVal = new WifiMetricsProto.RssiPollCount(); 4116 keyVal.rssi = histogram.keyAt(i); 4117 keyVal.count = histogram.valueAt(i); 4118 keyVal.frequency = frequency; 4119 rssis.add(keyVal); 4120 } 4121 } 4122 mWifiLogProto.rssiPollRssiCount = rssis.toArray(mWifiLogProto.rssiPollRssiCount); 4123 4124 /** 4125 * Convert the SparseIntArray of RSSI delta rssi's and counts to the proto's repeated 4126 * IntKeyVal array. 4127 */ 4128 mWifiLogProto.rssiPollDeltaCount = 4129 new WifiMetricsProto.RssiPollCount[mRssiDeltaCounts.size()]; 4130 for (int i = 0; i < mRssiDeltaCounts.size(); i++) { 4131 mWifiLogProto.rssiPollDeltaCount[i] = new WifiMetricsProto.RssiPollCount(); 4132 mWifiLogProto.rssiPollDeltaCount[i].rssi = mRssiDeltaCounts.keyAt(i); 4133 mWifiLogProto.rssiPollDeltaCount[i].count = mRssiDeltaCounts.valueAt(i); 4134 } 4135 4136 /** 4137 * Add LinkSpeedCount objects from mLinkSpeedCounts to proto. 4138 */ 4139 mWifiLogProto.linkSpeedCounts = 4140 new WifiMetricsProto.LinkSpeedCount[mLinkSpeedCounts.size()]; 4141 for (int i = 0; i < mLinkSpeedCounts.size(); i++) { 4142 mWifiLogProto.linkSpeedCounts[i] = mLinkSpeedCounts.valueAt(i); 4143 } 4144 4145 /** 4146 * Convert the SparseIntArray of alert reasons and counts to the proto's repeated 4147 * IntKeyVal array. 4148 */ 4149 mWifiLogProto.alertReasonCount = 4150 new WifiMetricsProto.AlertReasonCount[mWifiAlertReasonCounts.size()]; 4151 for (int i = 0; i < mWifiAlertReasonCounts.size(); i++) { 4152 mWifiLogProto.alertReasonCount[i] = new WifiMetricsProto.AlertReasonCount(); 4153 mWifiLogProto.alertReasonCount[i].reason = mWifiAlertReasonCounts.keyAt(i); 4154 mWifiLogProto.alertReasonCount[i].count = mWifiAlertReasonCounts.valueAt(i); 4155 } 4156 4157 /** 4158 * Convert the SparseIntArray of Wifi Score and counts to proto's repeated 4159 * IntKeyVal array. 4160 */ 4161 mWifiLogProto.wifiScoreCount = 4162 new WifiMetricsProto.WifiScoreCount[mWifiScoreCounts.size()]; 4163 for (int score = 0; score < mWifiScoreCounts.size(); score++) { 4164 mWifiLogProto.wifiScoreCount[score] = new WifiMetricsProto.WifiScoreCount(); 4165 mWifiLogProto.wifiScoreCount[score].score = mWifiScoreCounts.keyAt(score); 4166 mWifiLogProto.wifiScoreCount[score].count = mWifiScoreCounts.valueAt(score); 4167 } 4168 4169 /** 4170 * Convert the SparseIntArray of Wifi Usability Score and counts to proto's repeated 4171 * IntKeyVal array. 4172 */ 4173 mWifiLogProto.wifiUsabilityScoreCount = 4174 new WifiMetricsProto.WifiUsabilityScoreCount[mWifiUsabilityScoreCounts.size()]; 4175 for (int scoreIdx = 0; scoreIdx < mWifiUsabilityScoreCounts.size(); scoreIdx++) { 4176 mWifiLogProto.wifiUsabilityScoreCount[scoreIdx] = 4177 new WifiMetricsProto.WifiUsabilityScoreCount(); 4178 mWifiLogProto.wifiUsabilityScoreCount[scoreIdx].score = 4179 mWifiUsabilityScoreCounts.keyAt(scoreIdx); 4180 mWifiLogProto.wifiUsabilityScoreCount[scoreIdx].count = 4181 mWifiUsabilityScoreCounts.valueAt(scoreIdx); 4182 } 4183 4184 /** 4185 * Convert the SparseIntArray of SoftAp Return codes and counts to proto's repeated 4186 * IntKeyVal array. 4187 */ 4188 int codeCounts = mSoftApManagerReturnCodeCounts.size(); 4189 mWifiLogProto.softApReturnCode = new WifiMetricsProto.SoftApReturnCodeCount[codeCounts]; 4190 for (int sapCode = 0; sapCode < codeCounts; sapCode++) { 4191 mWifiLogProto.softApReturnCode[sapCode] = 4192 new WifiMetricsProto.SoftApReturnCodeCount(); 4193 mWifiLogProto.softApReturnCode[sapCode].startResult = 4194 mSoftApManagerReturnCodeCounts.keyAt(sapCode); 4195 mWifiLogProto.softApReturnCode[sapCode].count = 4196 mSoftApManagerReturnCodeCounts.valueAt(sapCode); 4197 } 4198 4199 /** 4200 * Convert StaEventList to array of StaEvents 4201 */ 4202 mWifiLogProto.staEventList = new StaEvent[mStaEventList.size()]; 4203 for (int i = 0; i < mStaEventList.size(); i++) { 4204 mWifiLogProto.staEventList[i] = mStaEventList.get(i).staEvent; 4205 } 4206 mWifiLogProto.userActionEvents = new UserActionEvent[mUserActionEventList.size()]; 4207 for (int i = 0; i < mUserActionEventList.size(); i++) { 4208 mWifiLogProto.userActionEvents[i] = mUserActionEventList.get(i).toProto(); 4209 } 4210 mWifiLogProto.totalSsidsInScanHistogram = 4211 makeNumConnectableNetworksBucketArray(mTotalSsidsInScanHistogram); 4212 mWifiLogProto.totalBssidsInScanHistogram = 4213 makeNumConnectableNetworksBucketArray(mTotalBssidsInScanHistogram); 4214 mWifiLogProto.availableOpenSsidsInScanHistogram = 4215 makeNumConnectableNetworksBucketArray(mAvailableOpenSsidsInScanHistogram); 4216 mWifiLogProto.availableOpenBssidsInScanHistogram = 4217 makeNumConnectableNetworksBucketArray(mAvailableOpenBssidsInScanHistogram); 4218 mWifiLogProto.availableSavedSsidsInScanHistogram = 4219 makeNumConnectableNetworksBucketArray(mAvailableSavedSsidsInScanHistogram); 4220 mWifiLogProto.availableSavedBssidsInScanHistogram = 4221 makeNumConnectableNetworksBucketArray(mAvailableSavedBssidsInScanHistogram); 4222 mWifiLogProto.availableOpenOrSavedSsidsInScanHistogram = 4223 makeNumConnectableNetworksBucketArray( 4224 mAvailableOpenOrSavedSsidsInScanHistogram); 4225 mWifiLogProto.availableOpenOrSavedBssidsInScanHistogram = 4226 makeNumConnectableNetworksBucketArray( 4227 mAvailableOpenOrSavedBssidsInScanHistogram); 4228 mWifiLogProto.availableSavedPasspointProviderProfilesInScanHistogram = 4229 makeNumConnectableNetworksBucketArray( 4230 mAvailableSavedPasspointProviderProfilesInScanHistogram); 4231 mWifiLogProto.availableSavedPasspointProviderBssidsInScanHistogram = 4232 makeNumConnectableNetworksBucketArray( 4233 mAvailableSavedPasspointProviderBssidsInScanHistogram); 4234 mWifiLogProto.wifiAwareLog = mWifiAwareMetrics.consolidateProto(); 4235 mWifiLogProto.wifiRttLog = mRttMetrics.consolidateProto(); 4236 4237 mWifiLogProto.pnoScanMetrics = mPnoScanMetrics; 4238 mWifiLogProto.wifiLinkLayerUsageStats = mWifiLinkLayerUsageStats; 4239 4240 /** 4241 * Convert the SparseIntArray of "Connect to Network" notification types and counts to 4242 * proto's repeated IntKeyVal array. 4243 */ 4244 ConnectToNetworkNotificationAndActionCount[] notificationCountArray = 4245 new ConnectToNetworkNotificationAndActionCount[ 4246 mConnectToNetworkNotificationCount.size()]; 4247 for (int i = 0; i < mConnectToNetworkNotificationCount.size(); i++) { 4248 ConnectToNetworkNotificationAndActionCount keyVal = 4249 new ConnectToNetworkNotificationAndActionCount(); 4250 keyVal.notification = mConnectToNetworkNotificationCount.keyAt(i); 4251 keyVal.recommender = 4252 ConnectToNetworkNotificationAndActionCount.RECOMMENDER_OPEN; 4253 keyVal.count = mConnectToNetworkNotificationCount.valueAt(i); 4254 notificationCountArray[i] = keyVal; 4255 } 4256 mWifiLogProto.connectToNetworkNotificationCount = notificationCountArray; 4257 4258 /** 4259 * Convert the SparseIntArray of "Connect to Network" notification types and counts to 4260 * proto's repeated IntKeyVal array. 4261 */ 4262 ConnectToNetworkNotificationAndActionCount[] notificationActionCountArray = 4263 new ConnectToNetworkNotificationAndActionCount[ 4264 mConnectToNetworkNotificationActionCount.size()]; 4265 for (int i = 0; i < mConnectToNetworkNotificationActionCount.size(); i++) { 4266 ConnectToNetworkNotificationAndActionCount keyVal = 4267 new ConnectToNetworkNotificationAndActionCount(); 4268 int k = mConnectToNetworkNotificationActionCount.keyAt(i); 4269 keyVal.notification = k / CONNECT_TO_NETWORK_NOTIFICATION_ACTION_KEY_MULTIPLIER; 4270 keyVal.action = k % CONNECT_TO_NETWORK_NOTIFICATION_ACTION_KEY_MULTIPLIER; 4271 keyVal.recommender = 4272 ConnectToNetworkNotificationAndActionCount.RECOMMENDER_OPEN; 4273 keyVal.count = mConnectToNetworkNotificationActionCount.valueAt(i); 4274 notificationActionCountArray[i] = keyVal; 4275 } 4276 4277 mWifiLogProto.installedPasspointProfileTypeForR1 = 4278 convertPasspointProfilesToProto(mInstalledPasspointProfileTypeForR1); 4279 mWifiLogProto.installedPasspointProfileTypeForR2 = 4280 convertPasspointProfilesToProto(mInstalledPasspointProfileTypeForR2); 4281 4282 mWifiLogProto.connectToNetworkNotificationActionCount = notificationActionCountArray; 4283 4284 mWifiLogProto.openNetworkRecommenderBlacklistSize = 4285 mOpenNetworkRecommenderBlacklistSize; 4286 mWifiLogProto.isWifiNetworksAvailableNotificationOn = 4287 mIsWifiNetworksAvailableNotificationOn; 4288 mWifiLogProto.numOpenNetworkRecommendationUpdates = 4289 mNumOpenNetworkRecommendationUpdates; 4290 mWifiLogProto.numOpenNetworkConnectMessageFailedToSend = 4291 mNumOpenNetworkConnectMessageFailedToSend; 4292 4293 mWifiLogProto.observedHotspotR1ApsInScanHistogram = 4294 makeNumConnectableNetworksBucketArray(mObservedHotspotR1ApInScanHistogram); 4295 mWifiLogProto.observedHotspotR2ApsInScanHistogram = 4296 makeNumConnectableNetworksBucketArray(mObservedHotspotR2ApInScanHistogram); 4297 mWifiLogProto.observedHotspotR3ApsInScanHistogram = 4298 makeNumConnectableNetworksBucketArray(mObservedHotspotR3ApInScanHistogram); 4299 mWifiLogProto.observedHotspotR1EssInScanHistogram = 4300 makeNumConnectableNetworksBucketArray(mObservedHotspotR1EssInScanHistogram); 4301 mWifiLogProto.observedHotspotR2EssInScanHistogram = 4302 makeNumConnectableNetworksBucketArray(mObservedHotspotR2EssInScanHistogram); 4303 mWifiLogProto.observedHotspotR3EssInScanHistogram = 4304 makeNumConnectableNetworksBucketArray(mObservedHotspotR3EssInScanHistogram); 4305 mWifiLogProto.observedHotspotR1ApsPerEssInScanHistogram = 4306 makeNumConnectableNetworksBucketArray( 4307 mObservedHotspotR1ApsPerEssInScanHistogram); 4308 mWifiLogProto.observedHotspotR2ApsPerEssInScanHistogram = 4309 makeNumConnectableNetworksBucketArray( 4310 mObservedHotspotR2ApsPerEssInScanHistogram); 4311 mWifiLogProto.observedHotspotR3ApsPerEssInScanHistogram = 4312 makeNumConnectableNetworksBucketArray( 4313 mObservedHotspotR3ApsPerEssInScanHistogram); 4314 4315 mWifiLogProto.observed80211McSupportingApsInScanHistogram = 4316 makeNumConnectableNetworksBucketArray(mObserved80211mcApInScanHistogram); 4317 4318 if (mSoftApEventListTethered.size() > 0) { 4319 mWifiLogProto.softApConnectedClientsEventsTethered = 4320 mSoftApEventListTethered.toArray( 4321 mWifiLogProto.softApConnectedClientsEventsTethered); 4322 } 4323 if (mSoftApEventListLocalOnly.size() > 0) { 4324 mWifiLogProto.softApConnectedClientsEventsLocalOnly = 4325 mSoftApEventListLocalOnly.toArray( 4326 mWifiLogProto.softApConnectedClientsEventsLocalOnly); 4327 } 4328 4329 mWifiLogProto.wifiPowerStats = mWifiPowerMetrics.buildProto(); 4330 mWifiLogProto.wifiRadioUsage = mWifiPowerMetrics.buildWifiRadioUsageProto(); 4331 mWifiLogProto.wifiWakeStats = mWifiWakeMetrics.buildProto(); 4332 mWifiLogProto.isMacRandomizationOn = mContext.getResources().getBoolean( 4333 R.bool.config_wifi_connected_mac_randomization_supported); 4334 mExperimentValues.wifiIsUnusableLoggingEnabled = mContext.getResources().getBoolean( 4335 R.bool.config_wifiIsUnusableEventMetricsEnabled); 4336 mExperimentValues.linkSpeedCountsLoggingEnabled = mContext.getResources().getBoolean( 4337 R.bool.config_wifiLinkSpeedMetricsEnabled); 4338 mExperimentValues.wifiDataStallMinTxBad = mContext.getResources().getInteger( 4339 R.integer.config_wifiDataStallMinTxBad); 4340 mExperimentValues.wifiDataStallMinTxSuccessWithoutRx = 4341 mContext.getResources().getInteger( 4342 R.integer.config_wifiDataStallMinTxSuccessWithoutRx); 4343 mWifiLogProto.experimentValues = mExperimentValues; 4344 mWifiLogProto.wifiIsUnusableEventList = 4345 new WifiIsUnusableEvent[mWifiIsUnusableList.size()]; 4346 for (int i = 0; i < mWifiIsUnusableList.size(); i++) { 4347 mWifiLogProto.wifiIsUnusableEventList[i] = mWifiIsUnusableList.get(i).event; 4348 } 4349 mWifiLogProto.hardwareRevision = SystemProperties.get("ro.boot.revision", ""); 4350 4351 // Postprocessing on WifiUsabilityStats to upload an equal number of LABEL_GOOD and 4352 // LABEL_BAD WifiUsabilityStats 4353 final int numUsabilityStats = Math.min( 4354 Math.min(mWifiUsabilityStatsListBad.size(), 4355 mWifiUsabilityStatsListGood.size()), 4356 MAX_WIFI_USABILITY_STATS_PER_TYPE_TO_UPLOAD); 4357 LinkedList<WifiUsabilityStats> usabilityStatsGoodCopy = 4358 new LinkedList<>(mWifiUsabilityStatsListGood); 4359 LinkedList<WifiUsabilityStats> usabilityStatsBadCopy = 4360 new LinkedList<>(mWifiUsabilityStatsListBad); 4361 mWifiLogProto.wifiUsabilityStatsList = new WifiUsabilityStats[numUsabilityStats * 2]; 4362 for (int i = 0; i < numUsabilityStats; i++) { 4363 mWifiLogProto.wifiUsabilityStatsList[2 * i] = usabilityStatsGoodCopy.remove( 4364 mRand.nextInt(usabilityStatsGoodCopy.size())); 4365 mWifiLogProto.wifiUsabilityStatsList[2 * i + 1] = usabilityStatsBadCopy.remove( 4366 mRand.nextInt(usabilityStatsBadCopy.size())); 4367 } 4368 mWifiLogProto.mobilityStatePnoStatsList = 4369 new DeviceMobilityStatePnoScanStats[mMobilityStatePnoStatsMap.size()]; 4370 for (int i = 0; i < mMobilityStatePnoStatsMap.size(); i++) { 4371 mWifiLogProto.mobilityStatePnoStatsList[i] = mMobilityStatePnoStatsMap.valueAt(i); 4372 } 4373 mWifiLogProto.wifiP2PStats = mWifiP2pMetrics.consolidateProto(); 4374 mWifiLogProto.wifiDppLog = mDppMetrics.consolidateProto(); 4375 mWifiLogProto.wifiConfigStoreIo = new WifiMetricsProto.WifiConfigStoreIO(); 4376 mWifiLogProto.wifiConfigStoreIo.readDurations = 4377 makeWifiConfigStoreIODurationBucketArray(mWifiConfigStoreReadDurationHistogram); 4378 mWifiLogProto.wifiConfigStoreIo.writeDurations = 4379 makeWifiConfigStoreIODurationBucketArray( 4380 mWifiConfigStoreWriteDurationHistogram); 4381 4382 LinkProbeStats linkProbeStats = new LinkProbeStats(); 4383 linkProbeStats.successRssiCounts = mLinkProbeSuccessRssiCounts.toProto(); 4384 linkProbeStats.failureRssiCounts = mLinkProbeFailureRssiCounts.toProto(); 4385 linkProbeStats.successLinkSpeedCounts = mLinkProbeSuccessLinkSpeedCounts.toProto(); 4386 linkProbeStats.failureLinkSpeedCounts = mLinkProbeFailureLinkSpeedCounts.toProto(); 4387 linkProbeStats.successSecondsSinceLastTxSuccessHistogram = 4388 mLinkProbeSuccessSecondsSinceLastTxSuccessHistogram.toProto(); 4389 linkProbeStats.failureSecondsSinceLastTxSuccessHistogram = 4390 mLinkProbeFailureSecondsSinceLastTxSuccessHistogram.toProto(); 4391 linkProbeStats.successElapsedTimeMsHistogram = 4392 mLinkProbeSuccessElapsedTimeMsHistogram.toProto(); 4393 linkProbeStats.failureReasonCounts = mLinkProbeFailureReasonCounts.toProto( 4394 LinkProbeFailureReasonCount.class, 4395 (reason, count) -> { 4396 LinkProbeFailureReasonCount c = new LinkProbeFailureReasonCount(); 4397 c.failureReason = linkProbeFailureReasonToProto(reason); 4398 c.count = count; 4399 return c; 4400 }); 4401 linkProbeStats.experimentProbeCounts = mLinkProbeExperimentProbeCounts.toProto( 4402 ExperimentProbeCounts.class, 4403 (experimentId, probeCount) -> { 4404 ExperimentProbeCounts c = new ExperimentProbeCounts(); 4405 c.experimentId = experimentId; 4406 c.probeCount = probeCount; 4407 return c; 4408 }); 4409 mWifiLogProto.linkProbeStats = linkProbeStats; 4410 4411 mWifiLogProto.networkSelectionExperimentDecisionsList = 4412 makeNetworkSelectionExperimentDecisionsList(); 4413 4414 mWifiNetworkRequestApiLog.networkMatchSizeHistogram = 4415 mWifiNetworkRequestApiMatchSizeHistogram.toProto(); 4416 mWifiLogProto.wifiNetworkRequestApiLog = mWifiNetworkRequestApiLog; 4417 4418 mWifiNetworkSuggestionApiLog.networkListSizeHistogram = 4419 mWifiNetworkSuggestionApiListSizeHistogram.toProto(); 4420 mWifiNetworkSuggestionApiLog.appCountPerType = 4421 mWifiNetworkSuggestionApiAppTypeCounter.toProto(SuggestionAppCount.class, 4422 (key, count) -> { 4423 SuggestionAppCount entry = new SuggestionAppCount(); 4424 entry.appType = key; 4425 entry.count = count; 4426 return entry; 4427 }); 4428 mWifiLogProto.wifiNetworkSuggestionApiLog = mWifiNetworkSuggestionApiLog; 4429 4430 UserReactionToApprovalUiEvent events = new UserReactionToApprovalUiEvent(); 4431 events.userApprovalAppUiReaction = mUserApprovalSuggestionAppUiReactionList 4432 .toArray(new UserReaction[0]); 4433 events.userApprovalCarrierUiReaction = mUserApprovalCarrierUiReactionList 4434 .toArray(new UserReaction[0]); 4435 mWifiLogProto.userReactionToApprovalUiEvent = events; 4436 4437 mWifiLockStats.highPerfLockAcqDurationSecHistogram = 4438 mWifiLockHighPerfAcqDurationSecHistogram.toProto(); 4439 4440 mWifiLockStats.lowLatencyLockAcqDurationSecHistogram = 4441 mWifiLockLowLatencyAcqDurationSecHistogram.toProto(); 4442 4443 mWifiLockStats.highPerfActiveSessionDurationSecHistogram = 4444 mWifiLockHighPerfActiveSessionDurationSecHistogram.toProto(); 4445 4446 mWifiLockStats.lowLatencyActiveSessionDurationSecHistogram = 4447 mWifiLockLowLatencyActiveSessionDurationSecHistogram.toProto(); 4448 4449 mWifiLogProto.wifiLockStats = mWifiLockStats; 4450 mWifiLogProto.wifiToggleStats = mWifiToggleStats; 4451 4452 /** 4453 * Convert the SparseIntArray of passpoint provision failure code 4454 * and counts to the proto's repeated IntKeyVal array. 4455 */ 4456 mWifiLogProto.passpointProvisionStats = new PasspointProvisionStats(); 4457 mWifiLogProto.passpointProvisionStats.numProvisionSuccess = mNumProvisionSuccess; 4458 mWifiLogProto.passpointProvisionStats.provisionFailureCount = 4459 mPasspointProvisionFailureCounts.toProto(ProvisionFailureCount.class, 4460 (key, count) -> { 4461 ProvisionFailureCount entry = new ProvisionFailureCount(); 4462 entry.failureCode = key; 4463 entry.count = count; 4464 return entry; 4465 }); 4466 // 'G' is due to that 1st Letter after _ becomes capital during protobuff compilation 4467 mWifiLogProto.txLinkSpeedCount2G = mTxLinkSpeedCount2g.toProto(); 4468 mWifiLogProto.txLinkSpeedCount5GLow = mTxLinkSpeedCount5gLow.toProto(); 4469 mWifiLogProto.txLinkSpeedCount5GMid = mTxLinkSpeedCount5gMid.toProto(); 4470 mWifiLogProto.txLinkSpeedCount5GHigh = mTxLinkSpeedCount5gHigh.toProto(); 4471 mWifiLogProto.txLinkSpeedCount6GLow = mTxLinkSpeedCount6gLow.toProto(); 4472 mWifiLogProto.txLinkSpeedCount6GMid = mTxLinkSpeedCount6gMid.toProto(); 4473 mWifiLogProto.txLinkSpeedCount6GHigh = mTxLinkSpeedCount6gHigh.toProto(); 4474 4475 mWifiLogProto.rxLinkSpeedCount2G = mRxLinkSpeedCount2g.toProto(); 4476 mWifiLogProto.rxLinkSpeedCount5GLow = mRxLinkSpeedCount5gLow.toProto(); 4477 mWifiLogProto.rxLinkSpeedCount5GMid = mRxLinkSpeedCount5gMid.toProto(); 4478 mWifiLogProto.rxLinkSpeedCount5GHigh = mRxLinkSpeedCount5gHigh.toProto(); 4479 mWifiLogProto.rxLinkSpeedCount6GLow = mRxLinkSpeedCount6gLow.toProto(); 4480 mWifiLogProto.rxLinkSpeedCount6GMid = mRxLinkSpeedCount6gMid.toProto(); 4481 mWifiLogProto.rxLinkSpeedCount6GHigh = mRxLinkSpeedCount6gHigh.toProto(); 4482 4483 HealthMonitorMetrics healthMonitorMetrics = mWifiHealthMonitor.buildProto(); 4484 if (healthMonitorMetrics != null) { 4485 mWifiLogProto.healthMonitorMetrics = healthMonitorMetrics; 4486 } 4487 mWifiLogProto.bssidBlocklistStats = mBssidBlocklistStats.toProto(); 4488 mWifiLogProto.connectionDurationStats = mConnectionDurationStats.toProto(); 4489 mWifiLogProto.wifiOffMetrics = mWifiOffMetrics.toProto(); 4490 mWifiLogProto.softApConfigLimitationMetrics = mSoftApConfigLimitationMetrics.toProto(); 4491 mWifiLogProto.channelUtilizationHistogram = 4492 new WifiMetricsProto.ChannelUtilizationHistogram(); 4493 mWifiLogProto.channelUtilizationHistogram.utilization2G = 4494 mChannelUtilizationHistogram2G.toProto(); 4495 mWifiLogProto.channelUtilizationHistogram.utilizationAbove2G = 4496 mChannelUtilizationHistogramAbove2G.toProto(); 4497 mWifiLogProto.throughputMbpsHistogram = 4498 new WifiMetricsProto.ThroughputMbpsHistogram(); 4499 mWifiLogProto.throughputMbpsHistogram.tx2G = 4500 mTxThroughputMbpsHistogram2G.toProto(); 4501 mWifiLogProto.throughputMbpsHistogram.txAbove2G = 4502 mTxThroughputMbpsHistogramAbove2G.toProto(); 4503 mWifiLogProto.throughputMbpsHistogram.rx2G = 4504 mRxThroughputMbpsHistogram2G.toProto(); 4505 mWifiLogProto.throughputMbpsHistogram.rxAbove2G = 4506 mRxThroughputMbpsHistogramAbove2G.toProto(); 4507 mWifiLogProto.meteredNetworkStatsSaved = mMeteredNetworkStatsBuilder.toProto(false); 4508 mWifiLogProto.meteredNetworkStatsSuggestion = mMeteredNetworkStatsBuilder.toProto(true); 4509 4510 InitPartialScanStats initialPartialScanStats = new InitPartialScanStats(); 4511 initialPartialScanStats.numScans = mInitPartialScanTotalCount; 4512 initialPartialScanStats.numSuccessScans = mInitPartialScanSuccessCount; 4513 initialPartialScanStats.numFailureScans = mInitPartialScanFailureCount; 4514 initialPartialScanStats.successfulScanChannelCountHistogram = 4515 mInitPartialScanSuccessHistogram.toProto(); 4516 initialPartialScanStats.failedScanChannelCountHistogram = 4517 mInitPartialScanFailureHistogram.toProto(); 4518 mWifiLogProto.initPartialScanStats = initialPartialScanStats; 4519 mWifiLogProto.carrierWifiMetrics = mCarrierWifiMetrics.toProto(); 4520 mWifiLogProto.mainlineModuleVersion = mWifiHealthMonitor.getWifiStackVersion(); 4521 4522 } 4523 } 4524 linkProbeFailureReasonToProto(int reason)4525 private static int linkProbeFailureReasonToProto(int reason) { 4526 switch (reason) { 4527 case WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED: 4528 return LinkProbeStats.LINK_PROBE_FAILURE_REASON_MCS_UNSUPPORTED; 4529 case WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_NO_ACK: 4530 return LinkProbeStats.LINK_PROBE_FAILURE_REASON_NO_ACK; 4531 case WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_TIMEOUT: 4532 return LinkProbeStats.LINK_PROBE_FAILURE_REASON_TIMEOUT; 4533 case WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_ALREADY_STARTED: 4534 return LinkProbeStats.LINK_PROBE_FAILURE_REASON_ALREADY_STARTED; 4535 default: 4536 return LinkProbeStats.LINK_PROBE_FAILURE_REASON_UNKNOWN; 4537 } 4538 } 4539 makeNetworkSelectionExperimentDecisionsList()4540 private NetworkSelectionExperimentDecisions[] makeNetworkSelectionExperimentDecisionsList() { 4541 NetworkSelectionExperimentDecisions[] results = new NetworkSelectionExperimentDecisions[ 4542 mNetworkSelectionExperimentPairNumChoicesCounts.size()]; 4543 int i = 0; 4544 for (Map.Entry<Pair<Integer, Integer>, NetworkSelectionExperimentResults> entry : 4545 mNetworkSelectionExperimentPairNumChoicesCounts.entrySet()) { 4546 NetworkSelectionExperimentDecisions result = new NetworkSelectionExperimentDecisions(); 4547 result.experiment1Id = entry.getKey().first; 4548 result.experiment2Id = entry.getKey().second; 4549 result.sameSelectionNumChoicesCounter = 4550 entry.getValue().sameSelectionNumChoicesCounter.toProto(); 4551 result.differentSelectionNumChoicesCounter = 4552 entry.getValue().differentSelectionNumChoicesCounter.toProto(); 4553 results[i] = result; 4554 i++; 4555 } 4556 return results; 4557 } 4558 4559 /** Sets the scoring experiment id to current value */ consolidateScoringParams()4560 private void consolidateScoringParams() { 4561 synchronized (mLock) { 4562 if (mScoringParams != null) { 4563 int experimentIdentifier = mScoringParams.getExperimentIdentifier(); 4564 if (experimentIdentifier == 0) { 4565 mWifiLogProto.scoreExperimentId = ""; 4566 } else { 4567 mWifiLogProto.scoreExperimentId = "x" + experimentIdentifier; 4568 } 4569 } 4570 } 4571 } 4572 makeNumConnectableNetworksBucketArray( SparseIntArray sia)4573 private WifiMetricsProto.NumConnectableNetworksBucket[] makeNumConnectableNetworksBucketArray( 4574 SparseIntArray sia) { 4575 WifiMetricsProto.NumConnectableNetworksBucket[] array = 4576 new WifiMetricsProto.NumConnectableNetworksBucket[sia.size()]; 4577 for (int i = 0; i < sia.size(); i++) { 4578 WifiMetricsProto.NumConnectableNetworksBucket keyVal = 4579 new WifiMetricsProto.NumConnectableNetworksBucket(); 4580 keyVal.numConnectableNetworks = sia.keyAt(i); 4581 keyVal.count = sia.valueAt(i); 4582 array[i] = keyVal; 4583 } 4584 return array; 4585 } 4586 4587 private WifiMetricsProto.WifiConfigStoreIO.DurationBucket[] makeWifiConfigStoreIODurationBucketArray(SparseIntArray sia)4588 makeWifiConfigStoreIODurationBucketArray(SparseIntArray sia) { 4589 MetricsUtils.GenericBucket[] genericBuckets = 4590 MetricsUtils.linearHistogramToGenericBuckets(sia, 4591 WIFI_CONFIG_STORE_IO_DURATION_BUCKET_RANGES_MS); 4592 WifiMetricsProto.WifiConfigStoreIO.DurationBucket[] array = 4593 new WifiMetricsProto.WifiConfigStoreIO.DurationBucket[genericBuckets.length]; 4594 try { 4595 for (int i = 0; i < genericBuckets.length; i++) { 4596 array[i] = new WifiMetricsProto.WifiConfigStoreIO.DurationBucket(); 4597 array[i].rangeStartMs = toIntExact(genericBuckets[i].start); 4598 array[i].rangeEndMs = toIntExact(genericBuckets[i].end); 4599 array[i].count = genericBuckets[i].count; 4600 } 4601 } catch (ArithmeticException e) { 4602 // Return empty array on any overflow errors. 4603 array = new WifiMetricsProto.WifiConfigStoreIO.DurationBucket[0]; 4604 } 4605 return array; 4606 } 4607 4608 /** 4609 * Clear all WifiMetrics, except for currentConnectionEvent and Open Network Notification 4610 * feature enabled state, blacklist size. 4611 */ clear()4612 private void clear() { 4613 synchronized (mLock) { 4614 mConnectionEventList.clear(); 4615 if (mCurrentConnectionEvent != null) { 4616 mConnectionEventList.add(mCurrentConnectionEvent); 4617 } 4618 mScanReturnEntries.clear(); 4619 mWifiSystemStateEntries.clear(); 4620 mRecordStartTimeSec = mClock.getElapsedSinceBootMillis() / 1000; 4621 mRssiPollCountsMap.clear(); 4622 mRssiDeltaCounts.clear(); 4623 mLinkSpeedCounts.clear(); 4624 mTxLinkSpeedCount2g.clear(); 4625 mTxLinkSpeedCount5gLow.clear(); 4626 mTxLinkSpeedCount5gMid.clear(); 4627 mTxLinkSpeedCount5gHigh.clear(); 4628 mTxLinkSpeedCount6gLow.clear(); 4629 mTxLinkSpeedCount6gMid.clear(); 4630 mTxLinkSpeedCount6gHigh.clear(); 4631 mRxLinkSpeedCount2g.clear(); 4632 mRxLinkSpeedCount5gLow.clear(); 4633 mRxLinkSpeedCount5gMid.clear(); 4634 mRxLinkSpeedCount5gHigh.clear(); 4635 mRxLinkSpeedCount6gLow.clear(); 4636 mRxLinkSpeedCount6gMid.clear(); 4637 mRxLinkSpeedCount6gHigh.clear(); 4638 mWifiAlertReasonCounts.clear(); 4639 mWifiScoreCounts.clear(); 4640 mWifiUsabilityScoreCounts.clear(); 4641 mWifiLogProto.clear(); 4642 mScanResultRssiTimestampMillis = -1; 4643 mSoftApManagerReturnCodeCounts.clear(); 4644 mStaEventList.clear(); 4645 mUserActionEventList.clear(); 4646 mWifiAwareMetrics.clear(); 4647 mRttMetrics.clear(); 4648 mTotalSsidsInScanHistogram.clear(); 4649 mTotalBssidsInScanHistogram.clear(); 4650 mAvailableOpenSsidsInScanHistogram.clear(); 4651 mAvailableOpenBssidsInScanHistogram.clear(); 4652 mAvailableSavedSsidsInScanHistogram.clear(); 4653 mAvailableSavedBssidsInScanHistogram.clear(); 4654 mAvailableOpenOrSavedSsidsInScanHistogram.clear(); 4655 mAvailableOpenOrSavedBssidsInScanHistogram.clear(); 4656 mAvailableSavedPasspointProviderProfilesInScanHistogram.clear(); 4657 mAvailableSavedPasspointProviderBssidsInScanHistogram.clear(); 4658 mPnoScanMetrics.clear(); 4659 mWifiLinkLayerUsageStats.clear(); 4660 mConnectToNetworkNotificationCount.clear(); 4661 mConnectToNetworkNotificationActionCount.clear(); 4662 mNumOpenNetworkRecommendationUpdates = 0; 4663 mNumOpenNetworkConnectMessageFailedToSend = 0; 4664 mObservedHotspotR1ApInScanHistogram.clear(); 4665 mObservedHotspotR2ApInScanHistogram.clear(); 4666 mObservedHotspotR3ApInScanHistogram.clear(); 4667 mObservedHotspotR1EssInScanHistogram.clear(); 4668 mObservedHotspotR2EssInScanHistogram.clear(); 4669 mObservedHotspotR3EssInScanHistogram.clear(); 4670 mObservedHotspotR1ApsPerEssInScanHistogram.clear(); 4671 mObservedHotspotR2ApsPerEssInScanHistogram.clear(); 4672 mObservedHotspotR3ApsPerEssInScanHistogram.clear(); 4673 mSoftApEventListTethered.clear(); 4674 mSoftApEventListLocalOnly.clear(); 4675 mWifiWakeMetrics.clear(); 4676 mObserved80211mcApInScanHistogram.clear(); 4677 mWifiIsUnusableList.clear(); 4678 mInstalledPasspointProfileTypeForR1.clear(); 4679 mInstalledPasspointProfileTypeForR2.clear(); 4680 mWifiUsabilityStatsListGood.clear(); 4681 mWifiUsabilityStatsListBad.clear(); 4682 mWifiUsabilityStatsEntriesList.clear(); 4683 mMobilityStatePnoStatsMap.clear(); 4684 mWifiP2pMetrics.clear(); 4685 mDppMetrics.clear(); 4686 mWifiUsabilityStatsCounter = 0; 4687 mLastBssid = null; 4688 mLastFrequency = -1; 4689 mSeqNumInsideFramework = 0; 4690 mLastWifiUsabilityScore = -1; 4691 mLastWifiUsabilityScoreNoReset = -1; 4692 mLastPredictionHorizonSec = -1; 4693 mLastPredictionHorizonSecNoReset = -1; 4694 mSeqNumToFramework = -1; 4695 mProbeStatusSinceLastUpdate = 4696 android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE; 4697 mProbeElapsedTimeSinceLastUpdateMs = -1; 4698 mProbeMcsRateSinceLastUpdate = -1; 4699 mScoreBreachLowTimeMillis = -1; 4700 mMeteredNetworkStatsBuilder.clear(); 4701 mWifiConfigStoreReadDurationHistogram.clear(); 4702 mWifiConfigStoreWriteDurationHistogram.clear(); 4703 mLinkProbeSuccessRssiCounts.clear(); 4704 mLinkProbeFailureRssiCounts.clear(); 4705 mLinkProbeSuccessLinkSpeedCounts.clear(); 4706 mLinkProbeFailureLinkSpeedCounts.clear(); 4707 mLinkProbeSuccessSecondsSinceLastTxSuccessHistogram.clear(); 4708 mLinkProbeFailureSecondsSinceLastTxSuccessHistogram.clear(); 4709 mLinkProbeSuccessElapsedTimeMsHistogram.clear(); 4710 mLinkProbeFailureReasonCounts.clear(); 4711 mLinkProbeExperimentProbeCounts.clear(); 4712 mLinkProbeStaEventCount = 0; 4713 mNetworkSelectionExperimentPairNumChoicesCounts.clear(); 4714 mWifiNetworkSuggestionApiLog.clear(); 4715 mWifiNetworkRequestApiMatchSizeHistogram.clear(); 4716 mWifiNetworkSuggestionApiListSizeHistogram.clear(); 4717 mWifiNetworkSuggestionApiAppTypeCounter.clear(); 4718 mUserApprovalSuggestionAppUiReactionList.clear(); 4719 mUserApprovalCarrierUiReactionList.clear(); 4720 mWifiLockHighPerfAcqDurationSecHistogram.clear(); 4721 mWifiLockLowLatencyAcqDurationSecHistogram.clear(); 4722 mWifiLockHighPerfActiveSessionDurationSecHistogram.clear(); 4723 mWifiLockLowLatencyActiveSessionDurationSecHistogram.clear(); 4724 mWifiLockStats.clear(); 4725 mWifiToggleStats.clear(); 4726 mChannelUtilizationHistogram2G.clear(); 4727 mChannelUtilizationHistogramAbove2G.clear(); 4728 mTxThroughputMbpsHistogram2G.clear(); 4729 mRxThroughputMbpsHistogram2G.clear(); 4730 mTxThroughputMbpsHistogramAbove2G.clear(); 4731 mRxThroughputMbpsHistogramAbove2G.clear(); 4732 mPasspointProvisionFailureCounts.clear(); 4733 mNumProvisionSuccess = 0; 4734 mBssidBlocklistStats = new BssidBlocklistStats(); 4735 mConnectionDurationStats.clear(); 4736 mWifiLogProto.isExternalWifiScorerOn = false; 4737 mWifiOffMetrics.clear(); 4738 mSoftApConfigLimitationMetrics.clear(); 4739 //Initial partial scan metrics 4740 mInitPartialScanTotalCount = 0; 4741 mInitPartialScanSuccessCount = 0; 4742 mInitPartialScanFailureCount = 0; 4743 mInitPartialScanSuccessHistogram.clear(); 4744 mInitPartialScanFailureHistogram.clear(); 4745 mCarrierWifiMetrics.clear(); 4746 } 4747 } 4748 4749 /** 4750 * Set screen state (On/Off) 4751 */ setScreenState(boolean screenOn)4752 public void setScreenState(boolean screenOn) { 4753 synchronized (mLock) { 4754 mScreenOn = screenOn; 4755 } 4756 } 4757 4758 /** 4759 * Set wifi state (WIFI_UNKNOWN, WIFI_DISABLED, WIFI_DISCONNECTED, WIFI_ASSOCIATED) 4760 */ setWifiState(int wifiState)4761 public void setWifiState(int wifiState) { 4762 synchronized (mLock) { 4763 mWifiState = wifiState; 4764 mWifiWins = (wifiState == WifiMetricsProto.WifiLog.WIFI_ASSOCIATED); 4765 mWifiWinsUsabilityScore = (wifiState == WifiMetricsProto.WifiLog.WIFI_ASSOCIATED); 4766 if (wifiState == WifiMetricsProto.WifiLog.WIFI_DISCONNECTED 4767 || wifiState == WifiMetricsProto.WifiLog.WIFI_DISABLED) { 4768 mWifiStatusBuilder = new WifiStatusBuilder(); 4769 } 4770 } 4771 } 4772 4773 /** 4774 * Message handler for interesting WifiMonitor messages. Generates StaEvents 4775 */ processMessage(Message msg)4776 private void processMessage(Message msg) { 4777 StaEvent event = new StaEvent(); 4778 boolean logEvent = true; 4779 switch (msg.what) { 4780 case WifiMonitor.ASSOCIATION_REJECTION_EVENT: 4781 event.type = StaEvent.TYPE_ASSOCIATION_REJECTION_EVENT; 4782 event.associationTimedOut = msg.arg1 > 0 ? true : false; 4783 event.status = msg.arg2; 4784 break; 4785 case WifiMonitor.AUTHENTICATION_FAILURE_EVENT: 4786 event.type = StaEvent.TYPE_AUTHENTICATION_FAILURE_EVENT; 4787 switch (msg.arg1) { 4788 case WifiManager.ERROR_AUTH_FAILURE_NONE: 4789 event.authFailureReason = StaEvent.AUTH_FAILURE_NONE; 4790 break; 4791 case WifiManager.ERROR_AUTH_FAILURE_TIMEOUT: 4792 event.authFailureReason = StaEvent.AUTH_FAILURE_TIMEOUT; 4793 break; 4794 case WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD: 4795 event.authFailureReason = StaEvent.AUTH_FAILURE_WRONG_PSWD; 4796 break; 4797 case WifiManager.ERROR_AUTH_FAILURE_EAP_FAILURE: 4798 event.authFailureReason = StaEvent.AUTH_FAILURE_EAP_FAILURE; 4799 break; 4800 default: 4801 break; 4802 } 4803 break; 4804 case WifiMonitor.NETWORK_CONNECTION_EVENT: 4805 event.type = StaEvent.TYPE_NETWORK_CONNECTION_EVENT; 4806 break; 4807 case WifiMonitor.NETWORK_DISCONNECTION_EVENT: 4808 event.type = StaEvent.TYPE_NETWORK_DISCONNECTION_EVENT; 4809 event.reason = msg.arg2; 4810 event.localGen = msg.arg1 == 0 ? false : true; 4811 break; 4812 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT: 4813 logEvent = false; 4814 StateChangeResult stateChangeResult = (StateChangeResult) msg.obj; 4815 mSupplicantStateChangeBitmask |= supplicantStateToBit(stateChangeResult.state); 4816 break; 4817 case WifiMonitor.ASSOCIATED_BSSID_EVENT: 4818 event.type = StaEvent.TYPE_CMD_ASSOCIATED_BSSID; 4819 break; 4820 case WifiMonitor.TARGET_BSSID_EVENT: 4821 event.type = StaEvent.TYPE_CMD_TARGET_BSSID; 4822 break; 4823 default: 4824 return; 4825 } 4826 if (logEvent) { 4827 addStaEvent(event); 4828 } 4829 } 4830 /** 4831 * Log a StaEvent from ClientModeImpl. The StaEvent must not be one of the supplicant 4832 * generated event types, which are logged through 'sendMessage' 4833 * @param type StaEvent.EventType describing the event 4834 */ logStaEvent(int type)4835 public void logStaEvent(int type) { 4836 logStaEvent(type, StaEvent.DISCONNECT_UNKNOWN, null); 4837 } 4838 /** 4839 * Log a StaEvent from ClientModeImpl. The StaEvent must not be one of the supplicant 4840 * generated event types, which are logged through 'sendMessage' 4841 * @param type StaEvent.EventType describing the event 4842 * @param config WifiConfiguration for a framework initiated connection attempt 4843 */ logStaEvent(int type, WifiConfiguration config)4844 public void logStaEvent(int type, WifiConfiguration config) { 4845 logStaEvent(type, StaEvent.DISCONNECT_UNKNOWN, config); 4846 } 4847 /** 4848 * Log a StaEvent from ClientModeImpl. The StaEvent must not be one of the supplicant 4849 * generated event types, which are logged through 'sendMessage' 4850 * @param type StaEvent.EventType describing the event 4851 * @param frameworkDisconnectReason StaEvent.FrameworkDisconnectReason explaining why framework 4852 * initiated a FRAMEWORK_DISCONNECT 4853 */ logStaEvent(int type, int frameworkDisconnectReason)4854 public void logStaEvent(int type, int frameworkDisconnectReason) { 4855 logStaEvent(type, frameworkDisconnectReason, null); 4856 } 4857 /** 4858 * Log a StaEvent from ClientModeImpl. The StaEvent must not be one of the supplicant 4859 * generated event types, which are logged through 'sendMessage' 4860 * @param type StaEvent.EventType describing the event 4861 * @param frameworkDisconnectReason StaEvent.FrameworkDisconnectReason explaining why framework 4862 * initiated a FRAMEWORK_DISCONNECT 4863 * @param config WifiConfiguration for a framework initiated connection attempt 4864 */ logStaEvent(int type, int frameworkDisconnectReason, WifiConfiguration config)4865 public void logStaEvent(int type, int frameworkDisconnectReason, WifiConfiguration config) { 4866 switch (type) { 4867 case StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL: 4868 case StaEvent.TYPE_CMD_IP_CONFIGURATION_LOST: 4869 case StaEvent.TYPE_CMD_IP_REACHABILITY_LOST: 4870 case StaEvent.TYPE_CMD_START_CONNECT: 4871 case StaEvent.TYPE_CMD_START_ROAM: 4872 case StaEvent.TYPE_CONNECT_NETWORK: 4873 case StaEvent.TYPE_NETWORK_AGENT_VALID_NETWORK: 4874 mWifiStatusBuilder.setValidated(true); 4875 case StaEvent.TYPE_FRAMEWORK_DISCONNECT: 4876 case StaEvent.TYPE_SCORE_BREACH: 4877 case StaEvent.TYPE_MAC_CHANGE: 4878 case StaEvent.TYPE_WIFI_ENABLED: 4879 case StaEvent.TYPE_WIFI_DISABLED: 4880 case StaEvent.TYPE_WIFI_USABILITY_SCORE_BREACH: 4881 break; 4882 default: 4883 Log.e(TAG, "Unknown StaEvent:" + type); 4884 return; 4885 } 4886 StaEvent event = new StaEvent(); 4887 event.type = type; 4888 if (frameworkDisconnectReason != StaEvent.DISCONNECT_UNKNOWN) { 4889 event.frameworkDisconnectReason = frameworkDisconnectReason; 4890 } 4891 event.configInfo = createConfigInfo(config); 4892 addStaEvent(event); 4893 } 4894 addStaEvent(StaEvent staEvent)4895 private void addStaEvent(StaEvent staEvent) { 4896 staEvent.startTimeMillis = mClock.getElapsedSinceBootMillis(); 4897 staEvent.lastRssi = mLastPollRssi; 4898 staEvent.lastFreq = mLastPollFreq; 4899 staEvent.lastLinkSpeed = mLastPollLinkSpeed; 4900 staEvent.supplicantStateChangesBitmask = mSupplicantStateChangeBitmask; 4901 staEvent.lastScore = mLastScore; 4902 staEvent.lastWifiUsabilityScore = mLastWifiUsabilityScore; 4903 staEvent.lastPredictionHorizonSec = mLastPredictionHorizonSec; 4904 staEvent.mobileTxBytes = mFacade.getMobileTxBytes(); 4905 staEvent.mobileRxBytes = mFacade.getMobileRxBytes(); 4906 staEvent.totalTxBytes = mFacade.getTotalTxBytes(); 4907 staEvent.totalRxBytes = mFacade.getTotalRxBytes(); 4908 staEvent.screenOn = mScreenOn; 4909 if (mWifiDataStall != null) { 4910 staEvent.isCellularDataAvailable = mWifiDataStall.isCellularDataAvailable(); 4911 } 4912 staEvent.isAdaptiveConnectivityEnabled = mAdaptiveConnectivityEnabled; 4913 mSupplicantStateChangeBitmask = 0; 4914 mLastPollRssi = -127; 4915 mLastPollFreq = -1; 4916 mLastPollLinkSpeed = -1; 4917 mLastPollRxLinkSpeed = -1; 4918 mLastScore = -1; 4919 mLastWifiUsabilityScore = -1; 4920 mLastPredictionHorizonSec = -1; 4921 synchronized (mLock) { 4922 mStaEventList.add(new StaEventWithTime(staEvent, mClock.getWallClockMillis())); 4923 // Prune StaEventList if it gets too long 4924 if (mStaEventList.size() > MAX_STA_EVENTS) mStaEventList.remove(); 4925 } 4926 } 4927 createConfigInfo(WifiConfiguration config)4928 private ConfigInfo createConfigInfo(WifiConfiguration config) { 4929 if (config == null) return null; 4930 ConfigInfo info = new ConfigInfo(); 4931 info.allowedKeyManagement = bitSetToInt(config.allowedKeyManagement); 4932 info.allowedProtocols = bitSetToInt(config.allowedProtocols); 4933 info.allowedAuthAlgorithms = bitSetToInt(config.allowedAuthAlgorithms); 4934 info.allowedPairwiseCiphers = bitSetToInt(config.allowedPairwiseCiphers); 4935 info.allowedGroupCiphers = bitSetToInt(config.allowedGroupCiphers); 4936 info.hiddenSsid = config.hiddenSSID; 4937 info.isPasspoint = config.isPasspoint(); 4938 info.isEphemeral = config.isEphemeral(); 4939 info.hasEverConnected = config.getNetworkSelectionStatus().hasEverConnected(); 4940 ScanResult candidate = config.getNetworkSelectionStatus().getCandidate(); 4941 if (candidate != null) { 4942 info.scanRssi = candidate.level; 4943 info.scanFreq = candidate.frequency; 4944 } 4945 return info; 4946 } 4947 getHandler()4948 public Handler getHandler() { 4949 return mHandler; 4950 } 4951 getWifiAwareMetrics()4952 public WifiAwareMetrics getWifiAwareMetrics() { 4953 return mWifiAwareMetrics; 4954 } 4955 getWakeupMetrics()4956 public WifiWakeMetrics getWakeupMetrics() { 4957 return mWifiWakeMetrics; 4958 } 4959 getRttMetrics()4960 public RttMetrics getRttMetrics() { 4961 return mRttMetrics; 4962 } 4963 4964 // Rather than generate a StaEvent for each SUPPLICANT_STATE_CHANGE, cache these in a bitmask 4965 // and attach it to the next event which is generated. 4966 private int mSupplicantStateChangeBitmask = 0; 4967 4968 /** 4969 * Converts a SupplicantState value to a single bit, with position defined by 4970 * {@code StaEvent.SupplicantState} 4971 */ supplicantStateToBit(SupplicantState state)4972 public static int supplicantStateToBit(SupplicantState state) { 4973 switch(state) { 4974 case DISCONNECTED: 4975 return 1 << StaEvent.STATE_DISCONNECTED; 4976 case INTERFACE_DISABLED: 4977 return 1 << StaEvent.STATE_INTERFACE_DISABLED; 4978 case INACTIVE: 4979 return 1 << StaEvent.STATE_INACTIVE; 4980 case SCANNING: 4981 return 1 << StaEvent.STATE_SCANNING; 4982 case AUTHENTICATING: 4983 return 1 << StaEvent.STATE_AUTHENTICATING; 4984 case ASSOCIATING: 4985 return 1 << StaEvent.STATE_ASSOCIATING; 4986 case ASSOCIATED: 4987 return 1 << StaEvent.STATE_ASSOCIATED; 4988 case FOUR_WAY_HANDSHAKE: 4989 return 1 << StaEvent.STATE_FOUR_WAY_HANDSHAKE; 4990 case GROUP_HANDSHAKE: 4991 return 1 << StaEvent.STATE_GROUP_HANDSHAKE; 4992 case COMPLETED: 4993 return 1 << StaEvent.STATE_COMPLETED; 4994 case DORMANT: 4995 return 1 << StaEvent.STATE_DORMANT; 4996 case UNINITIALIZED: 4997 return 1 << StaEvent.STATE_UNINITIALIZED; 4998 case INVALID: 4999 return 1 << StaEvent.STATE_INVALID; 5000 default: 5001 Log.wtf(TAG, "Got unknown supplicant state: " + state.ordinal()); 5002 return 0; 5003 } 5004 } 5005 supplicantStateChangesBitmaskToString(int mask)5006 private static String supplicantStateChangesBitmaskToString(int mask) { 5007 StringBuilder sb = new StringBuilder(); 5008 sb.append("supplicantStateChangeEvents: {"); 5009 if ((mask & (1 << StaEvent.STATE_DISCONNECTED)) > 0) sb.append(" DISCONNECTED"); 5010 if ((mask & (1 << StaEvent.STATE_INTERFACE_DISABLED)) > 0) sb.append(" INTERFACE_DISABLED"); 5011 if ((mask & (1 << StaEvent.STATE_INACTIVE)) > 0) sb.append(" INACTIVE"); 5012 if ((mask & (1 << StaEvent.STATE_SCANNING)) > 0) sb.append(" SCANNING"); 5013 if ((mask & (1 << StaEvent.STATE_AUTHENTICATING)) > 0) sb.append(" AUTHENTICATING"); 5014 if ((mask & (1 << StaEvent.STATE_ASSOCIATING)) > 0) sb.append(" ASSOCIATING"); 5015 if ((mask & (1 << StaEvent.STATE_ASSOCIATED)) > 0) sb.append(" ASSOCIATED"); 5016 if ((mask & (1 << StaEvent.STATE_FOUR_WAY_HANDSHAKE)) > 0) sb.append(" FOUR_WAY_HANDSHAKE"); 5017 if ((mask & (1 << StaEvent.STATE_GROUP_HANDSHAKE)) > 0) sb.append(" GROUP_HANDSHAKE"); 5018 if ((mask & (1 << StaEvent.STATE_COMPLETED)) > 0) sb.append(" COMPLETED"); 5019 if ((mask & (1 << StaEvent.STATE_DORMANT)) > 0) sb.append(" DORMANT"); 5020 if ((mask & (1 << StaEvent.STATE_UNINITIALIZED)) > 0) sb.append(" UNINITIALIZED"); 5021 if ((mask & (1 << StaEvent.STATE_INVALID)) > 0) sb.append(" INVALID"); 5022 sb.append(" }"); 5023 return sb.toString(); 5024 } 5025 5026 /** 5027 * Returns a human readable string from a Sta Event. Only adds information relevant to the event 5028 * type. 5029 */ staEventToString(StaEvent event)5030 public static String staEventToString(StaEvent event) { 5031 if (event == null) return "<NULL>"; 5032 StringBuilder sb = new StringBuilder(); 5033 switch (event.type) { 5034 case StaEvent.TYPE_ASSOCIATION_REJECTION_EVENT: 5035 sb.append("ASSOCIATION_REJECTION_EVENT") 5036 .append(" timedOut=").append(event.associationTimedOut) 5037 .append(" status=").append(event.status).append(":") 5038 .append(ISupplicantStaIfaceCallback.StatusCode.toString(event.status)); 5039 break; 5040 case StaEvent.TYPE_AUTHENTICATION_FAILURE_EVENT: 5041 sb.append("AUTHENTICATION_FAILURE_EVENT reason=").append(event.authFailureReason) 5042 .append(":").append(authFailureReasonToString(event.authFailureReason)); 5043 break; 5044 case StaEvent.TYPE_NETWORK_CONNECTION_EVENT: 5045 sb.append("NETWORK_CONNECTION_EVENT"); 5046 break; 5047 case StaEvent.TYPE_NETWORK_DISCONNECTION_EVENT: 5048 sb.append("NETWORK_DISCONNECTION_EVENT") 5049 .append(" local_gen=").append(event.localGen) 5050 .append(" reason=").append(event.reason).append(":") 5051 .append(ISupplicantStaIfaceCallback.ReasonCode.toString( 5052 (event.reason >= 0 ? event.reason : -1 * event.reason))); 5053 break; 5054 case StaEvent.TYPE_CMD_ASSOCIATED_BSSID: 5055 sb.append("CMD_ASSOCIATED_BSSID"); 5056 break; 5057 case StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL: 5058 sb.append("CMD_IP_CONFIGURATION_SUCCESSFUL"); 5059 break; 5060 case StaEvent.TYPE_CMD_IP_CONFIGURATION_LOST: 5061 sb.append("CMD_IP_CONFIGURATION_LOST"); 5062 break; 5063 case StaEvent.TYPE_CMD_IP_REACHABILITY_LOST: 5064 sb.append("CMD_IP_REACHABILITY_LOST"); 5065 break; 5066 case StaEvent.TYPE_CMD_TARGET_BSSID: 5067 sb.append("CMD_TARGET_BSSID"); 5068 break; 5069 case StaEvent.TYPE_CMD_START_CONNECT: 5070 sb.append("CMD_START_CONNECT"); 5071 break; 5072 case StaEvent.TYPE_CMD_START_ROAM: 5073 sb.append("CMD_START_ROAM"); 5074 break; 5075 case StaEvent.TYPE_CONNECT_NETWORK: 5076 sb.append("CONNECT_NETWORK"); 5077 break; 5078 case StaEvent.TYPE_NETWORK_AGENT_VALID_NETWORK: 5079 sb.append("NETWORK_AGENT_VALID_NETWORK"); 5080 break; 5081 case StaEvent.TYPE_FRAMEWORK_DISCONNECT: 5082 sb.append("FRAMEWORK_DISCONNECT") 5083 .append(" reason=") 5084 .append(frameworkDisconnectReasonToString(event.frameworkDisconnectReason)); 5085 break; 5086 case StaEvent.TYPE_SCORE_BREACH: 5087 sb.append("SCORE_BREACH"); 5088 break; 5089 case StaEvent.TYPE_MAC_CHANGE: 5090 sb.append("MAC_CHANGE"); 5091 break; 5092 case StaEvent.TYPE_WIFI_ENABLED: 5093 sb.append("WIFI_ENABLED"); 5094 break; 5095 case StaEvent.TYPE_WIFI_DISABLED: 5096 sb.append("WIFI_DISABLED"); 5097 break; 5098 case StaEvent.TYPE_WIFI_USABILITY_SCORE_BREACH: 5099 sb.append("WIFI_USABILITY_SCORE_BREACH"); 5100 break; 5101 case StaEvent.TYPE_LINK_PROBE: 5102 sb.append("LINK_PROBE"); 5103 sb.append(" linkProbeWasSuccess=").append(event.linkProbeWasSuccess); 5104 if (event.linkProbeWasSuccess) { 5105 sb.append(" linkProbeSuccessElapsedTimeMs=") 5106 .append(event.linkProbeSuccessElapsedTimeMs); 5107 } else { 5108 sb.append(" linkProbeFailureReason=").append(event.linkProbeFailureReason); 5109 } 5110 break; 5111 default: 5112 sb.append("UNKNOWN " + event.type + ":"); 5113 break; 5114 } 5115 if (event.lastRssi != -127) sb.append(" lastRssi=").append(event.lastRssi); 5116 if (event.lastFreq != -1) sb.append(" lastFreq=").append(event.lastFreq); 5117 if (event.lastLinkSpeed != -1) sb.append(" lastLinkSpeed=").append(event.lastLinkSpeed); 5118 if (event.lastScore != -1) sb.append(" lastScore=").append(event.lastScore); 5119 if (event.lastWifiUsabilityScore != -1) { 5120 sb.append(" lastWifiUsabilityScore=").append(event.lastWifiUsabilityScore); 5121 sb.append(" lastPredictionHorizonSec=").append(event.lastPredictionHorizonSec); 5122 } 5123 if (event.mobileTxBytes > 0) sb.append(" mobileTxBytes=").append(event.mobileTxBytes); 5124 if (event.mobileRxBytes > 0) sb.append(" mobileRxBytes=").append(event.mobileRxBytes); 5125 if (event.totalTxBytes > 0) sb.append(" totalTxBytes=").append(event.totalTxBytes); 5126 if (event.totalRxBytes > 0) sb.append(" totalRxBytes=").append(event.totalRxBytes); 5127 sb.append(" screenOn=").append(event.screenOn); 5128 sb.append(" cellularData=").append(event.isCellularDataAvailable); 5129 sb.append(" adaptiveConnectivity=").append(event.isAdaptiveConnectivityEnabled); 5130 if (event.supplicantStateChangesBitmask != 0) { 5131 sb.append(", ").append(supplicantStateChangesBitmaskToString( 5132 event.supplicantStateChangesBitmask)); 5133 } 5134 if (event.configInfo != null) { 5135 sb.append(", ").append(configInfoToString(event.configInfo)); 5136 } 5137 5138 return sb.toString(); 5139 } 5140 authFailureReasonToString(int authFailureReason)5141 private static String authFailureReasonToString(int authFailureReason) { 5142 switch (authFailureReason) { 5143 case StaEvent.AUTH_FAILURE_NONE: 5144 return "ERROR_AUTH_FAILURE_NONE"; 5145 case StaEvent.AUTH_FAILURE_TIMEOUT: 5146 return "ERROR_AUTH_FAILURE_TIMEOUT"; 5147 case StaEvent.AUTH_FAILURE_WRONG_PSWD: 5148 return "ERROR_AUTH_FAILURE_WRONG_PSWD"; 5149 case StaEvent.AUTH_FAILURE_EAP_FAILURE: 5150 return "ERROR_AUTH_FAILURE_EAP_FAILURE"; 5151 default: 5152 return ""; 5153 } 5154 } 5155 frameworkDisconnectReasonToString(int frameworkDisconnectReason)5156 private static String frameworkDisconnectReasonToString(int frameworkDisconnectReason) { 5157 switch (frameworkDisconnectReason) { 5158 case StaEvent.DISCONNECT_API: 5159 return "DISCONNECT_API"; 5160 case StaEvent.DISCONNECT_GENERIC: 5161 return "DISCONNECT_GENERIC"; 5162 case StaEvent.DISCONNECT_UNWANTED: 5163 return "DISCONNECT_UNWANTED"; 5164 case StaEvent.DISCONNECT_ROAM_WATCHDOG_TIMER: 5165 return "DISCONNECT_ROAM_WATCHDOG_TIMER"; 5166 case StaEvent.DISCONNECT_P2P_DISCONNECT_WIFI_REQUEST: 5167 return "DISCONNECT_P2P_DISCONNECT_WIFI_REQUEST"; 5168 case StaEvent.DISCONNECT_RESET_SIM_NETWORKS: 5169 return "DISCONNECT_RESET_SIM_NETWORKS"; 5170 default: 5171 return "DISCONNECT_UNKNOWN=" + frameworkDisconnectReason; 5172 } 5173 } 5174 configInfoToString(ConfigInfo info)5175 private static String configInfoToString(ConfigInfo info) { 5176 StringBuilder sb = new StringBuilder(); 5177 sb.append("ConfigInfo:") 5178 .append(" allowed_key_management=").append(info.allowedKeyManagement) 5179 .append(" allowed_protocols=").append(info.allowedProtocols) 5180 .append(" allowed_auth_algorithms=").append(info.allowedAuthAlgorithms) 5181 .append(" allowed_pairwise_ciphers=").append(info.allowedPairwiseCiphers) 5182 .append(" allowed_group_ciphers=").append(info.allowedGroupCiphers) 5183 .append(" hidden_ssid=").append(info.hiddenSsid) 5184 .append(" is_passpoint=").append(info.isPasspoint) 5185 .append(" is_ephemeral=").append(info.isEphemeral) 5186 .append(" has_ever_connected=").append(info.hasEverConnected) 5187 .append(" scan_rssi=").append(info.scanRssi) 5188 .append(" scan_freq=").append(info.scanFreq); 5189 return sb.toString(); 5190 } 5191 5192 /** 5193 * Converts the first 31 bits of a BitSet to a little endian int 5194 */ bitSetToInt(BitSet bits)5195 private static int bitSetToInt(BitSet bits) { 5196 int value = 0; 5197 int nBits = bits.length() < 31 ? bits.length() : 31; 5198 for (int i = 0; i < nBits; i++) { 5199 value += bits.get(i) ? (1 << i) : 0; 5200 } 5201 return value; 5202 } 5203 private void incrementSsid(SparseIntArray sia, int element) { 5204 increment(sia, Math.min(element, MAX_CONNECTABLE_SSID_NETWORK_BUCKET)); 5205 } 5206 private void incrementBssid(SparseIntArray sia, int element) { 5207 increment(sia, Math.min(element, MAX_CONNECTABLE_BSSID_NETWORK_BUCKET)); 5208 } 5209 private void incrementTotalScanResults(SparseIntArray sia, int element) { 5210 increment(sia, Math.min(element, MAX_TOTAL_SCAN_RESULTS_BUCKET)); 5211 } 5212 private void incrementTotalScanSsids(SparseIntArray sia, int element) { 5213 increment(sia, Math.min(element, MAX_TOTAL_SCAN_RESULT_SSIDS_BUCKET)); 5214 } 5215 private void incrementTotalPasspointAps(SparseIntArray sia, int element) { 5216 increment(sia, Math.min(element, MAX_TOTAL_PASSPOINT_APS_BUCKET)); 5217 } 5218 private void incrementTotalUniquePasspointEss(SparseIntArray sia, int element) { 5219 increment(sia, Math.min(element, MAX_TOTAL_PASSPOINT_UNIQUE_ESS_BUCKET)); 5220 } 5221 private void incrementPasspointPerUniqueEss(SparseIntArray sia, int element) { 5222 increment(sia, Math.min(element, MAX_PASSPOINT_APS_PER_UNIQUE_ESS_BUCKET)); 5223 } 5224 private void increment80211mcAps(SparseIntArray sia, int element) { 5225 increment(sia, Math.min(element, MAX_TOTAL_80211MC_APS_BUCKET)); 5226 } 5227 private void increment(SparseIntArray sia, int element) { 5228 int count = sia.get(element); 5229 sia.put(element, count + 1); 5230 } 5231 5232 private static class StaEventWithTime { 5233 public StaEvent staEvent; 5234 public long wallClockMillis; 5235 5236 StaEventWithTime(StaEvent event, long wallClockMillis) { 5237 staEvent = event; 5238 this.wallClockMillis = wallClockMillis; 5239 } 5240 5241 public String toString() { 5242 StringBuilder sb = new StringBuilder(); 5243 Calendar c = Calendar.getInstance(); 5244 c.setTimeInMillis(wallClockMillis); 5245 if (wallClockMillis != 0) { 5246 sb.append(String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)); 5247 } else { 5248 sb.append(" "); 5249 } 5250 sb.append(" ").append(staEventToString(staEvent)); 5251 return sb.toString(); 5252 } 5253 } 5254 5255 private LinkedList<WifiIsUnusableWithTime> mWifiIsUnusableList = 5256 new LinkedList<WifiIsUnusableWithTime>(); 5257 private long mTxScucessDelta = 0; 5258 private long mTxRetriesDelta = 0; 5259 private long mTxBadDelta = 0; 5260 private long mRxSuccessDelta = 0; 5261 private long mLlStatsUpdateTimeDelta = 0; 5262 private long mLlStatsLastUpdateTime = 0; 5263 private int mLastScoreNoReset = -1; 5264 private long mLastDataStallTime = Long.MIN_VALUE; 5265 5266 private static class WifiIsUnusableWithTime { 5267 public WifiIsUnusableEvent event; 5268 public long wallClockMillis; 5269 5270 WifiIsUnusableWithTime(WifiIsUnusableEvent event, long wallClockMillis) { 5271 this.event = event; 5272 this.wallClockMillis = wallClockMillis; 5273 } 5274 5275 public String toString() { 5276 if (event == null) return "<NULL>"; 5277 StringBuilder sb = new StringBuilder(); 5278 if (wallClockMillis != 0) { 5279 Calendar c = Calendar.getInstance(); 5280 c.setTimeInMillis(wallClockMillis); 5281 sb.append(String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)); 5282 } else { 5283 sb.append(" "); 5284 } 5285 sb.append(" "); 5286 5287 switch(event.type) { 5288 case WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX: 5289 sb.append("DATA_STALL_BAD_TX"); 5290 break; 5291 case WifiIsUnusableEvent.TYPE_DATA_STALL_TX_WITHOUT_RX: 5292 sb.append("DATA_STALL_TX_WITHOUT_RX"); 5293 break; 5294 case WifiIsUnusableEvent.TYPE_DATA_STALL_BOTH: 5295 sb.append("DATA_STALL_BOTH"); 5296 break; 5297 case WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT: 5298 sb.append("FIRMWARE_ALERT"); 5299 break; 5300 case WifiIsUnusableEvent.TYPE_IP_REACHABILITY_LOST: 5301 sb.append("IP_REACHABILITY_LOST"); 5302 break; 5303 default: 5304 sb.append("UNKNOWN " + event.type); 5305 break; 5306 } 5307 5308 sb.append(" lastScore=").append(event.lastScore); 5309 sb.append(" txSuccessDelta=").append(event.txSuccessDelta); 5310 sb.append(" txRetriesDelta=").append(event.txRetriesDelta); 5311 sb.append(" txBadDelta=").append(event.txBadDelta); 5312 sb.append(" rxSuccessDelta=").append(event.rxSuccessDelta); 5313 sb.append(" packetUpdateTimeDelta=").append(event.packetUpdateTimeDelta) 5314 .append("ms"); 5315 if (event.firmwareAlertCode != -1) { 5316 sb.append(" firmwareAlertCode=").append(event.firmwareAlertCode); 5317 } 5318 sb.append(" lastWifiUsabilityScore=").append(event.lastWifiUsabilityScore); 5319 sb.append(" lastPredictionHorizonSec=").append(event.lastPredictionHorizonSec); 5320 sb.append(" screenOn=").append(event.screenOn); 5321 sb.append(" mobileTxBytes=").append(event.mobileTxBytes); 5322 sb.append(" mobileRxBytes=").append(event.mobileRxBytes); 5323 sb.append(" totalTxBytes=").append(event.totalTxBytes); 5324 sb.append(" totalRxBytes=").append(event.totalRxBytes); 5325 return sb.toString(); 5326 } 5327 } 5328 5329 /** 5330 * Converts MeteredOverride enum to UserActionEvent type. 5331 * @param value 5332 */ 5333 public static int convertMeteredOverrideEnumToUserActionEventType(@MeteredOverride int value) { 5334 int result = UserActionEvent.EVENT_UNKNOWN; 5335 switch(value) { 5336 case WifiConfiguration.METERED_OVERRIDE_NONE: 5337 result = UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_AUTO; 5338 break; 5339 case WifiConfiguration.METERED_OVERRIDE_METERED: 5340 result = UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_METERED; 5341 break; 5342 case WifiConfiguration.METERED_OVERRIDE_NOT_METERED: 5343 result = UserActionEvent.EVENT_CONFIGURE_METERED_STATUS_UNMETERED; 5344 break; 5345 } 5346 return result; 5347 } 5348 5349 /** 5350 * Converts Adaptive Connectivity state to UserActionEvent type. 5351 * @param value 5352 */ 5353 public static int convertAdaptiveConnectivityStateToUserActionEventType(boolean value) { 5354 return value ? UserActionEvent.EVENT_CONFIGURE_ADAPTIVE_CONNECTIVITY_ON 5355 : UserActionEvent.EVENT_CONFIGURE_ADAPTIVE_CONNECTIVITY_OFF; 5356 } 5357 5358 static class MeteredNetworkStatsBuilder { 5359 // A map from network identifier to MeteredDetail 5360 Map<String, MeteredDetail> mNetworkMap = new ArrayMap<>(); 5361 5362 void put(WifiConfiguration config, boolean detectedAsMetered) { 5363 MeteredDetail meteredDetail = new MeteredDetail(); 5364 boolean isMetered = detectedAsMetered; 5365 if (config.meteredOverride == WifiConfiguration.METERED_OVERRIDE_METERED) { 5366 isMetered = true; 5367 } else if (config.meteredOverride == WifiConfiguration.METERED_OVERRIDE_NOT_METERED) { 5368 isMetered = false; 5369 } 5370 meteredDetail.isMetered = isMetered; 5371 meteredDetail.isMeteredOverrideSet = config.meteredOverride 5372 != WifiConfiguration.METERED_OVERRIDE_NONE; 5373 meteredDetail.isFromSuggestion = config.fromWifiNetworkSuggestion; 5374 mNetworkMap.put(config.getKey(), meteredDetail); 5375 } 5376 5377 void clear() { 5378 mNetworkMap.clear(); 5379 } 5380 5381 MeteredNetworkStats toProto(boolean isFromSuggestion) { 5382 MeteredNetworkStats result = new MeteredNetworkStats(); 5383 for (MeteredDetail meteredDetail : mNetworkMap.values()) { 5384 if (meteredDetail.isFromSuggestion != isFromSuggestion) { 5385 continue; 5386 } 5387 if (meteredDetail.isMetered) { 5388 result.numMetered++; 5389 } else { 5390 result.numUnmetered++; 5391 } 5392 if (meteredDetail.isMeteredOverrideSet) { 5393 if (meteredDetail.isMetered) { 5394 result.numOverrideMetered++; 5395 } else { 5396 result.numOverrideUnmetered++; 5397 } 5398 } 5399 } 5400 return result; 5401 } 5402 5403 static class MeteredDetail { 5404 public boolean isMetered; 5405 public boolean isMeteredOverrideSet; 5406 public boolean isFromSuggestion; 5407 } 5408 } 5409 5410 /** 5411 * Add metered information of this network. 5412 * @param config WifiConfiguration representing the netework. 5413 * @param detectedAsMetered is the network detected as metered. 5414 */ 5415 public void addMeteredStat(WifiConfiguration config, boolean detectedAsMetered) { 5416 synchronized (mLock) { 5417 if (config == null) { 5418 return; 5419 } 5420 mMeteredNetworkStatsBuilder.put(config, detectedAsMetered); 5421 } 5422 } 5423 /** 5424 * Logs a UserActionEvent without a target network. 5425 * @param eventType the type of user action (one of WifiMetricsProto.UserActionEvent.EventType) 5426 */ 5427 public void logUserActionEvent(int eventType) { 5428 logUserActionEvent(eventType, -1); 5429 } 5430 5431 /** 5432 * Logs a UserActionEvent which has a target network. 5433 * @param eventType the type of user action (one of WifiMetricsProto.UserActionEvent.EventType) 5434 * @param networkId networkId of the target network. 5435 */ 5436 public void logUserActionEvent(int eventType, int networkId) { 5437 synchronized (mLock) { 5438 mUserActionEventList.add(new UserActionEventWithTime(eventType, networkId)); 5439 if (mUserActionEventList.size() > MAX_USER_ACTION_EVENTS) { 5440 mUserActionEventList.remove(); 5441 } 5442 } 5443 } 5444 5445 /** 5446 * Logs a UserActionEvent, directly specifying the target network's properties. 5447 * @param eventType the type of user action (one of WifiMetricsProto.UserActionEvent.EventType) 5448 * @param isEphemeral true if the target network is ephemeral. 5449 * @param isPasspoint true if the target network is passpoint. 5450 */ 5451 public void logUserActionEvent(int eventType, boolean isEphemeral, boolean isPasspoint) { 5452 synchronized (mLock) { 5453 TargetNetworkInfo networkInfo = new TargetNetworkInfo(); 5454 networkInfo.isEphemeral = isEphemeral; 5455 networkInfo.isPasspoint = isPasspoint; 5456 mUserActionEventList.add(new UserActionEventWithTime(eventType, networkInfo)); 5457 if (mUserActionEventList.size() > MAX_USER_ACTION_EVENTS) { 5458 mUserActionEventList.remove(); 5459 } 5460 } 5461 } 5462 5463 /** 5464 * Update the difference between the last two WifiLinkLayerStats for WifiIsUnusableEvent 5465 */ 5466 public void updateWifiIsUnusableLinkLayerStats(long txSuccessDelta, long txRetriesDelta, 5467 long txBadDelta, long rxSuccessDelta, long updateTimeDelta) { 5468 mTxScucessDelta = txSuccessDelta; 5469 mTxRetriesDelta = txRetriesDelta; 5470 mTxBadDelta = txBadDelta; 5471 mRxSuccessDelta = rxSuccessDelta; 5472 mLlStatsUpdateTimeDelta = updateTimeDelta; 5473 mLlStatsLastUpdateTime = mClock.getElapsedSinceBootMillis(); 5474 } 5475 5476 /** 5477 * Clear the saved difference between the last two WifiLinkLayerStats 5478 */ 5479 public void resetWifiIsUnusableLinkLayerStats() { 5480 mTxScucessDelta = 0; 5481 mTxRetriesDelta = 0; 5482 mTxBadDelta = 0; 5483 mRxSuccessDelta = 0; 5484 mLlStatsUpdateTimeDelta = 0; 5485 mLlStatsLastUpdateTime = 0; 5486 mLastDataStallTime = Long.MIN_VALUE; 5487 } 5488 5489 /** 5490 * Log a WifiIsUnusableEvent 5491 * @param triggerType WifiIsUnusableEvent.type describing the event 5492 */ 5493 public void logWifiIsUnusableEvent(int triggerType) { 5494 logWifiIsUnusableEvent(triggerType, -1); 5495 } 5496 5497 /** 5498 * Log a WifiIsUnusableEvent 5499 * @param triggerType WifiIsUnusableEvent.type describing the event 5500 * @param firmwareAlertCode WifiIsUnusableEvent.firmwareAlertCode for firmware alert code 5501 */ 5502 public void logWifiIsUnusableEvent(int triggerType, int firmwareAlertCode) { 5503 mScoreBreachLowTimeMillis = -1; 5504 if (!mContext.getResources().getBoolean(R.bool.config_wifiIsUnusableEventMetricsEnabled)) { 5505 return; 5506 } 5507 5508 long currentBootTime = mClock.getElapsedSinceBootMillis(); 5509 switch (triggerType) { 5510 case WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX: 5511 case WifiIsUnusableEvent.TYPE_DATA_STALL_TX_WITHOUT_RX: 5512 case WifiIsUnusableEvent.TYPE_DATA_STALL_BOTH: 5513 // Have a time-based throttle for generating WifiIsUnusableEvent from data stalls 5514 if (currentBootTime < mLastDataStallTime + MIN_DATA_STALL_WAIT_MS) { 5515 return; 5516 } 5517 mLastDataStallTime = currentBootTime; 5518 break; 5519 case WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT: 5520 break; 5521 case WifiIsUnusableEvent.TYPE_IP_REACHABILITY_LOST: 5522 break; 5523 default: 5524 Log.e(TAG, "Unknown WifiIsUnusableEvent: " + triggerType); 5525 return; 5526 } 5527 5528 WifiIsUnusableEvent event = new WifiIsUnusableEvent(); 5529 event.type = triggerType; 5530 if (triggerType == WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT) { 5531 event.firmwareAlertCode = firmwareAlertCode; 5532 } 5533 event.startTimeMillis = currentBootTime; 5534 event.lastScore = mLastScoreNoReset; 5535 event.lastWifiUsabilityScore = mLastWifiUsabilityScoreNoReset; 5536 event.lastPredictionHorizonSec = mLastPredictionHorizonSecNoReset; 5537 event.txSuccessDelta = mTxScucessDelta; 5538 event.txRetriesDelta = mTxRetriesDelta; 5539 event.txBadDelta = mTxBadDelta; 5540 event.rxSuccessDelta = mRxSuccessDelta; 5541 event.packetUpdateTimeDelta = mLlStatsUpdateTimeDelta; 5542 event.lastLinkLayerStatsUpdateTime = mLlStatsLastUpdateTime; 5543 event.screenOn = mScreenOn; 5544 event.mobileTxBytes = mFacade.getMobileTxBytes(); 5545 event.mobileRxBytes = mFacade.getMobileRxBytes(); 5546 event.totalTxBytes = mFacade.getTotalTxBytes(); 5547 event.totalRxBytes = mFacade.getTotalRxBytes(); 5548 5549 mWifiIsUnusableList.add(new WifiIsUnusableWithTime(event, mClock.getWallClockMillis())); 5550 if (mWifiIsUnusableList.size() > MAX_UNUSABLE_EVENTS) { 5551 mWifiIsUnusableList.removeFirst(); 5552 } 5553 } 5554 5555 /** 5556 * Extract data from |info| and |stats| to build a WifiUsabilityStatsEntry and then adds it 5557 * into an internal ring buffer. 5558 * @param info 5559 * @param stats 5560 */ 5561 public void updateWifiUsabilityStatsEntries(WifiInfo info, WifiLinkLayerStats stats) { 5562 synchronized (mLock) { 5563 if (info == null) { 5564 return; 5565 } 5566 if (stats == null) { 5567 // For devices lacking vendor hal, fill in the parts that we can 5568 stats = new WifiLinkLayerStats(); 5569 stats.timeStampInMs = mClock.getElapsedSinceBootMillis(); 5570 stats.txmpdu_be = info.txSuccess; 5571 stats.retries_be = info.txRetries; 5572 stats.lostmpdu_be = info.txBad; 5573 stats.rxmpdu_be = info.rxSuccess; 5574 } 5575 WifiUsabilityStatsEntry wifiUsabilityStatsEntry = 5576 mWifiUsabilityStatsEntriesList.size() 5577 < MAX_WIFI_USABILITY_STATS_ENTRIES_LIST_SIZE 5578 ? new WifiUsabilityStatsEntry() : mWifiUsabilityStatsEntriesList.remove(); 5579 wifiUsabilityStatsEntry.timeStampMs = stats.timeStampInMs; 5580 wifiUsabilityStatsEntry.totalTxSuccess = stats.txmpdu_be + stats.txmpdu_bk 5581 + stats.txmpdu_vi + stats.txmpdu_vo; 5582 wifiUsabilityStatsEntry.totalTxRetries = stats.retries_be + stats.retries_bk 5583 + stats.retries_vi + stats.retries_vo; 5584 wifiUsabilityStatsEntry.totalTxBad = stats.lostmpdu_be + stats.lostmpdu_bk 5585 + stats.lostmpdu_vi + stats.lostmpdu_vo; 5586 wifiUsabilityStatsEntry.totalRxSuccess = stats.rxmpdu_be + stats.rxmpdu_bk 5587 + stats.rxmpdu_vi + stats.rxmpdu_vo; 5588 wifiUsabilityStatsEntry.totalRadioOnTimeMs = stats.on_time; 5589 wifiUsabilityStatsEntry.totalRadioTxTimeMs = stats.tx_time; 5590 wifiUsabilityStatsEntry.totalRadioRxTimeMs = stats.rx_time; 5591 wifiUsabilityStatsEntry.totalScanTimeMs = stats.on_time_scan; 5592 wifiUsabilityStatsEntry.totalNanScanTimeMs = stats.on_time_nan_scan; 5593 wifiUsabilityStatsEntry.totalBackgroundScanTimeMs = stats.on_time_background_scan; 5594 wifiUsabilityStatsEntry.totalRoamScanTimeMs = stats.on_time_roam_scan; 5595 wifiUsabilityStatsEntry.totalPnoScanTimeMs = stats.on_time_pno_scan; 5596 wifiUsabilityStatsEntry.totalHotspot2ScanTimeMs = stats.on_time_hs20_scan; 5597 wifiUsabilityStatsEntry.rssi = info.getRssi(); 5598 wifiUsabilityStatsEntry.linkSpeedMbps = info.getLinkSpeed(); 5599 WifiLinkLayerStats.ChannelStats statsMap = 5600 stats.channelStatsMap.get(info.getFrequency()); 5601 if (statsMap != null) { 5602 wifiUsabilityStatsEntry.totalRadioOnFreqTimeMs = statsMap.radioOnTimeMs; 5603 wifiUsabilityStatsEntry.totalCcaBusyFreqTimeMs = statsMap.ccaBusyTimeMs; 5604 } 5605 wifiUsabilityStatsEntry.totalBeaconRx = stats.beacon_rx; 5606 5607 boolean isSameBssidAndFreq = mLastBssid == null || mLastFrequency == -1 5608 || (mLastBssid.equals(info.getBSSID()) 5609 && mLastFrequency == info.getFrequency()); 5610 mLastBssid = info.getBSSID(); 5611 mLastFrequency = info.getFrequency(); 5612 wifiUsabilityStatsEntry.wifiScore = mLastScoreNoReset; 5613 wifiUsabilityStatsEntry.wifiUsabilityScore = mLastWifiUsabilityScoreNoReset; 5614 wifiUsabilityStatsEntry.seqNumToFramework = mSeqNumToFramework; 5615 wifiUsabilityStatsEntry.predictionHorizonSec = mLastPredictionHorizonSecNoReset; 5616 switch (mProbeStatusSinceLastUpdate) { 5617 case android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE: 5618 wifiUsabilityStatsEntry.probeStatusSinceLastUpdate = 5619 WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE; 5620 break; 5621 case android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS: 5622 wifiUsabilityStatsEntry.probeStatusSinceLastUpdate = 5623 WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS; 5624 break; 5625 case android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE: 5626 wifiUsabilityStatsEntry.probeStatusSinceLastUpdate = 5627 WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE; 5628 break; 5629 default: 5630 wifiUsabilityStatsEntry.probeStatusSinceLastUpdate = 5631 WifiUsabilityStatsEntry.PROBE_STATUS_UNKNOWN; 5632 Log.e(TAG, "Unknown link probe status: " + mProbeStatusSinceLastUpdate); 5633 } 5634 wifiUsabilityStatsEntry.probeElapsedTimeSinceLastUpdateMs = 5635 mProbeElapsedTimeSinceLastUpdateMs; 5636 wifiUsabilityStatsEntry.probeMcsRateSinceLastUpdate = mProbeMcsRateSinceLastUpdate; 5637 wifiUsabilityStatsEntry.rxLinkSpeedMbps = info.getRxLinkSpeedMbps(); 5638 wifiUsabilityStatsEntry.isSameBssidAndFreq = isSameBssidAndFreq; 5639 wifiUsabilityStatsEntry.seqNumInsideFramework = mSeqNumInsideFramework; 5640 wifiUsabilityStatsEntry.deviceMobilityState = mCurrentDeviceMobilityState; 5641 5642 mWifiUsabilityStatsEntriesList.add(wifiUsabilityStatsEntry); 5643 mWifiUsabilityStatsCounter++; 5644 if (mWifiUsabilityStatsCounter >= NUM_WIFI_USABILITY_STATS_ENTRIES_PER_WIFI_GOOD) { 5645 addToWifiUsabilityStatsList(WifiUsabilityStats.LABEL_GOOD, 5646 WifiUsabilityStats.TYPE_UNKNOWN, -1); 5647 } 5648 if (mScoreBreachLowTimeMillis != -1) { 5649 long elapsedTime = mClock.getElapsedSinceBootMillis() - mScoreBreachLowTimeMillis; 5650 if (elapsedTime >= MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS) { 5651 mScoreBreachLowTimeMillis = -1; 5652 if (elapsedTime <= VALIDITY_PERIOD_OF_SCORE_BREACH_LOW_MS) { 5653 addToWifiUsabilityStatsList(WifiUsabilityStats.LABEL_GOOD, 5654 WifiUsabilityStats.TYPE_UNKNOWN, -1); 5655 } 5656 } 5657 } 5658 5659 // Invoke Wifi usability stats listener. 5660 sendWifiUsabilityStats(mSeqNumInsideFramework, isSameBssidAndFreq, 5661 createNewWifiUsabilityStatsEntryParcelable(wifiUsabilityStatsEntry)); 5662 5663 mSeqNumInsideFramework++; 5664 mProbeStatusSinceLastUpdate = 5665 android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE; 5666 mProbeElapsedTimeSinceLastUpdateMs = -1; 5667 mProbeMcsRateSinceLastUpdate = -1; 5668 } 5669 } 5670 5671 /** 5672 * Send Wifi usability stats. 5673 * @param seqNum 5674 * @param isSameBssidAndFreq 5675 * @param statsEntry 5676 */ 5677 private void sendWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq, 5678 android.net.wifi.WifiUsabilityStatsEntry statsEntry) { 5679 for (IOnWifiUsabilityStatsListener listener : mOnWifiUsabilityListeners.getCallbacks()) { 5680 try { 5681 listener.onWifiUsabilityStats(seqNum, isSameBssidAndFreq, statsEntry); 5682 } catch (RemoteException e) { 5683 Log.e(TAG, "Unable to invoke Wifi usability stats entry listener " 5684 + listener, e); 5685 } 5686 } 5687 } 5688 5689 private android.net.wifi.WifiUsabilityStatsEntry createNewWifiUsabilityStatsEntryParcelable( 5690 WifiUsabilityStatsEntry s) { 5691 int probeStatus; 5692 switch (s.probeStatusSinceLastUpdate) { 5693 case WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE: 5694 probeStatus = android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE; 5695 break; 5696 case WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS: 5697 probeStatus = android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS; 5698 break; 5699 case WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE: 5700 probeStatus = android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE; 5701 break; 5702 default: 5703 probeStatus = android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_UNKNOWN; 5704 Log.e(TAG, "Unknown link probe status: " + s.probeStatusSinceLastUpdate); 5705 } 5706 // TODO: remove the following hardcoded values once if they are removed from public API 5707 return new android.net.wifi.WifiUsabilityStatsEntry(s.timeStampMs, s.rssi, 5708 s.linkSpeedMbps, s.totalTxSuccess, s.totalTxRetries, 5709 s.totalTxBad, s.totalRxSuccess, s.totalRadioOnTimeMs, 5710 s.totalRadioTxTimeMs, s.totalRadioRxTimeMs, s.totalScanTimeMs, 5711 s.totalNanScanTimeMs, s.totalBackgroundScanTimeMs, s.totalRoamScanTimeMs, 5712 s.totalPnoScanTimeMs, s.totalHotspot2ScanTimeMs, s.totalCcaBusyFreqTimeMs, 5713 s.totalRadioOnFreqTimeMs, s.totalBeaconRx, probeStatus, 5714 s.probeElapsedTimeSinceLastUpdateMs, s.probeMcsRateSinceLastUpdate, 5715 s.rxLinkSpeedMbps, 0, 0, 0, false 5716 ); 5717 } 5718 5719 private WifiUsabilityStatsEntry createNewWifiUsabilityStatsEntry(WifiUsabilityStatsEntry s) { 5720 WifiUsabilityStatsEntry out = new WifiUsabilityStatsEntry(); 5721 out.timeStampMs = s.timeStampMs; 5722 out.totalTxSuccess = s.totalTxSuccess; 5723 out.totalTxRetries = s.totalTxRetries; 5724 out.totalTxBad = s.totalTxBad; 5725 out.totalRxSuccess = s.totalRxSuccess; 5726 out.totalRadioOnTimeMs = s.totalRadioOnTimeMs; 5727 out.totalRadioTxTimeMs = s.totalRadioTxTimeMs; 5728 out.totalRadioRxTimeMs = s.totalRadioRxTimeMs; 5729 out.totalScanTimeMs = s.totalScanTimeMs; 5730 out.totalNanScanTimeMs = s.totalNanScanTimeMs; 5731 out.totalBackgroundScanTimeMs = s.totalBackgroundScanTimeMs; 5732 out.totalRoamScanTimeMs = s.totalRoamScanTimeMs; 5733 out.totalPnoScanTimeMs = s.totalPnoScanTimeMs; 5734 out.totalHotspot2ScanTimeMs = s.totalHotspot2ScanTimeMs; 5735 out.rssi = s.rssi; 5736 out.linkSpeedMbps = s.linkSpeedMbps; 5737 out.totalCcaBusyFreqTimeMs = s.totalCcaBusyFreqTimeMs; 5738 out.totalRadioOnFreqTimeMs = s.totalRadioOnFreqTimeMs; 5739 out.totalBeaconRx = s.totalBeaconRx; 5740 out.wifiScore = s.wifiScore; 5741 out.wifiUsabilityScore = s.wifiUsabilityScore; 5742 out.seqNumToFramework = s.seqNumToFramework; 5743 out.predictionHorizonSec = s.predictionHorizonSec; 5744 out.probeStatusSinceLastUpdate = s.probeStatusSinceLastUpdate; 5745 out.probeElapsedTimeSinceLastUpdateMs = s.probeElapsedTimeSinceLastUpdateMs; 5746 out.probeMcsRateSinceLastUpdate = s.probeMcsRateSinceLastUpdate; 5747 out.rxLinkSpeedMbps = s.rxLinkSpeedMbps; 5748 out.isSameBssidAndFreq = s.isSameBssidAndFreq; 5749 out.seqNumInsideFramework = s.seqNumInsideFramework; 5750 out.deviceMobilityState = s.deviceMobilityState; 5751 return out; 5752 } 5753 5754 private WifiUsabilityStats createWifiUsabilityStatsWithLabel(int label, int triggerType, 5755 int firmwareAlertCode) { 5756 WifiUsabilityStats wifiUsabilityStats = new WifiUsabilityStats(); 5757 wifiUsabilityStats.label = label; 5758 wifiUsabilityStats.triggerType = triggerType; 5759 wifiUsabilityStats.firmwareAlertCode = firmwareAlertCode; 5760 wifiUsabilityStats.timeStampMs = mClock.getElapsedSinceBootMillis(); 5761 wifiUsabilityStats.stats = 5762 new WifiUsabilityStatsEntry[mWifiUsabilityStatsEntriesList.size()]; 5763 for (int i = 0; i < mWifiUsabilityStatsEntriesList.size(); i++) { 5764 wifiUsabilityStats.stats[i] = 5765 createNewWifiUsabilityStatsEntry(mWifiUsabilityStatsEntriesList.get(i)); 5766 } 5767 return wifiUsabilityStats; 5768 } 5769 5770 /** 5771 * Label the current snapshot of WifiUsabilityStatsEntrys and save the labeled data in memory. 5772 * @param label WifiUsabilityStats.LABEL_GOOD or WifiUsabilityStats.LABEL_BAD 5773 * @param triggerType what event triggers WifiUsabilityStats 5774 * @param firmwareAlertCode the firmware alert code when the stats was triggered by a 5775 * firmware alert 5776 */ 5777 public void addToWifiUsabilityStatsList(int label, int triggerType, int firmwareAlertCode) { 5778 synchronized (mLock) { 5779 if (mWifiUsabilityStatsEntriesList.isEmpty() || !mScreenOn) { 5780 return; 5781 } 5782 if (label == WifiUsabilityStats.LABEL_GOOD) { 5783 // Only add a good event if at least |MIN_WIFI_GOOD_USABILITY_STATS_PERIOD_MS| 5784 // has passed. 5785 if (mWifiUsabilityStatsListGood.isEmpty() 5786 || mWifiUsabilityStatsListGood.getLast().stats[mWifiUsabilityStatsListGood 5787 .getLast().stats.length - 1].timeStampMs 5788 + MIN_WIFI_GOOD_USABILITY_STATS_PERIOD_MS 5789 < mWifiUsabilityStatsEntriesList.getLast().timeStampMs) { 5790 while (mWifiUsabilityStatsListGood.size() 5791 >= MAX_WIFI_USABILITY_STATS_LIST_SIZE_PER_TYPE) { 5792 mWifiUsabilityStatsListGood.remove( 5793 mRand.nextInt(mWifiUsabilityStatsListGood.size())); 5794 } 5795 mWifiUsabilityStatsListGood.add( 5796 createWifiUsabilityStatsWithLabel(label, triggerType, 5797 firmwareAlertCode)); 5798 } 5799 } else { 5800 // Only add a bad event if at least |MIN_DATA_STALL_WAIT_MS| 5801 // has passed. 5802 mScoreBreachLowTimeMillis = -1; 5803 if (mWifiUsabilityStatsListBad.isEmpty() 5804 || (mWifiUsabilityStatsListBad.getLast().stats[mWifiUsabilityStatsListBad 5805 .getLast().stats.length - 1].timeStampMs 5806 + MIN_DATA_STALL_WAIT_MS 5807 < mWifiUsabilityStatsEntriesList.getLast().timeStampMs)) { 5808 while (mWifiUsabilityStatsListBad.size() 5809 >= MAX_WIFI_USABILITY_STATS_LIST_SIZE_PER_TYPE) { 5810 mWifiUsabilityStatsListBad.remove( 5811 mRand.nextInt(mWifiUsabilityStatsListBad.size())); 5812 } 5813 mWifiUsabilityStatsListBad.add( 5814 createWifiUsabilityStatsWithLabel(label, triggerType, 5815 firmwareAlertCode)); 5816 } 5817 } 5818 mWifiUsabilityStatsCounter = 0; 5819 mWifiUsabilityStatsEntriesList.clear(); 5820 } 5821 } 5822 5823 private DeviceMobilityStatePnoScanStats getOrCreateDeviceMobilityStatePnoScanStats( 5824 @DeviceMobilityState int deviceMobilityState) { 5825 DeviceMobilityStatePnoScanStats stats = mMobilityStatePnoStatsMap.get(deviceMobilityState); 5826 if (stats == null) { 5827 stats = new DeviceMobilityStatePnoScanStats(); 5828 stats.deviceMobilityState = deviceMobilityState; 5829 stats.numTimesEnteredState = 0; 5830 stats.totalDurationMs = 0; 5831 stats.pnoDurationMs = 0; 5832 mMobilityStatePnoStatsMap.put(deviceMobilityState, stats); 5833 } 5834 return stats; 5835 } 5836 5837 /** 5838 * Updates the current device mobility state's total duration. This method should be called 5839 * before entering a new device mobility state. 5840 */ 5841 private void updateCurrentMobilityStateTotalDuration(long now) { 5842 DeviceMobilityStatePnoScanStats stats = 5843 getOrCreateDeviceMobilityStatePnoScanStats(mCurrentDeviceMobilityState); 5844 stats.totalDurationMs += now - mCurrentDeviceMobilityStateStartMs; 5845 mCurrentDeviceMobilityStateStartMs = now; 5846 } 5847 5848 /** 5849 * Convert the IntCounter of passpoint profile types and counts to proto's 5850 * repeated IntKeyVal array. 5851 * 5852 * @param passpointProfileTypes passpoint profile types and counts. 5853 */ 5854 private PasspointProfileTypeCount[] convertPasspointProfilesToProto( 5855 IntCounter passpointProfileTypes) { 5856 return passpointProfileTypes.toProto(PasspointProfileTypeCount.class, (key, count) -> { 5857 PasspointProfileTypeCount entry = new PasspointProfileTypeCount(); 5858 entry.eapMethodType = key; 5859 entry.count = count; 5860 return entry; 5861 }); 5862 } 5863 5864 /** 5865 * Reports that the device entered a new mobility state. 5866 * 5867 * @param newState the new device mobility state. 5868 */ 5869 public void enterDeviceMobilityState(@DeviceMobilityState int newState) { 5870 synchronized (mLock) { 5871 long now = mClock.getElapsedSinceBootMillis(); 5872 updateCurrentMobilityStateTotalDuration(now); 5873 5874 if (newState == mCurrentDeviceMobilityState) return; 5875 5876 mCurrentDeviceMobilityState = newState; 5877 DeviceMobilityStatePnoScanStats stats = 5878 getOrCreateDeviceMobilityStatePnoScanStats(mCurrentDeviceMobilityState); 5879 stats.numTimesEnteredState++; 5880 } 5881 } 5882 5883 /** 5884 * Logs the start of a PNO scan. 5885 */ 5886 public void logPnoScanStart() { 5887 synchronized (mLock) { 5888 long now = mClock.getElapsedSinceBootMillis(); 5889 mCurrentDeviceMobilityStatePnoScanStartMs = now; 5890 updateCurrentMobilityStateTotalDuration(now); 5891 } 5892 } 5893 5894 /** 5895 * Logs the end of a PNO scan. This is attributed to the current device mobility state, as 5896 * logged by {@link #enterDeviceMobilityState(int)}. Thus, if the mobility state changes during 5897 * a PNO scan, one should call {@link #logPnoScanStop()}, {@link #enterDeviceMobilityState(int)} 5898 * , then {@link #logPnoScanStart()} so that the portion of PNO scan before the mobility state 5899 * change can be correctly attributed to the previous mobility state. 5900 */ 5901 public void logPnoScanStop() { 5902 synchronized (mLock) { 5903 if (mCurrentDeviceMobilityStatePnoScanStartMs < 0) { 5904 Log.e(TAG, "Called WifiMetrics#logPNoScanStop() without calling " 5905 + "WifiMetrics#logPnoScanStart() first!"); 5906 return; 5907 } 5908 DeviceMobilityStatePnoScanStats stats = 5909 getOrCreateDeviceMobilityStatePnoScanStats(mCurrentDeviceMobilityState); 5910 long now = mClock.getElapsedSinceBootMillis(); 5911 stats.pnoDurationMs += now - mCurrentDeviceMobilityStatePnoScanStartMs; 5912 mCurrentDeviceMobilityStatePnoScanStartMs = -1; 5913 updateCurrentMobilityStateTotalDuration(now); 5914 } 5915 } 5916 5917 /** 5918 * Add a new listener for Wi-Fi usability stats handling. 5919 */ 5920 public void addOnWifiUsabilityListener(IBinder binder, IOnWifiUsabilityStatsListener listener, 5921 int listenerIdentifier) { 5922 if (!mOnWifiUsabilityListeners.add(binder, listener, listenerIdentifier)) { 5923 Log.e(TAG, "Failed to add listener"); 5924 return; 5925 } 5926 if (DBG) { 5927 Log.v(TAG, "Adding listener. Num listeners: " 5928 + mOnWifiUsabilityListeners.getNumCallbacks()); 5929 } 5930 } 5931 5932 /** 5933 * Remove an existing listener for Wi-Fi usability stats handling. 5934 */ 5935 public void removeOnWifiUsabilityListener(int listenerIdentifier) { 5936 mOnWifiUsabilityListeners.remove(listenerIdentifier); 5937 if (DBG) { 5938 Log.v(TAG, "Removing listener. Num listeners: " 5939 + mOnWifiUsabilityListeners.getNumCallbacks()); 5940 } 5941 } 5942 5943 /** 5944 * Updates the Wi-Fi usability score and increments occurence of a particular Wifi usability 5945 * score passed in from outside framework. Scores are bounded within 5946 * [MIN_WIFI_USABILITY_SCORE, MAX_WIFI_USABILITY_SCORE]. 5947 * 5948 * Also records events when the Wifi usability score breaches significant thresholds. 5949 * 5950 * @param seqNum Sequence number of the Wi-Fi usability score. 5951 * @param score The Wi-Fi usability score. 5952 * @param predictionHorizonSec Prediction horizon of the Wi-Fi usability score. 5953 */ 5954 public void incrementWifiUsabilityScoreCount(int seqNum, int score, int predictionHorizonSec) { 5955 if (score < MIN_WIFI_USABILITY_SCORE || score > MAX_WIFI_USABILITY_SCORE) { 5956 return; 5957 } 5958 synchronized (mLock) { 5959 mSeqNumToFramework = seqNum; 5960 mLastWifiUsabilityScore = score; 5961 mLastWifiUsabilityScoreNoReset = score; 5962 mWifiUsabilityScoreCounts.put(score, mWifiUsabilityScoreCounts.get(score) + 1); 5963 mLastPredictionHorizonSec = predictionHorizonSec; 5964 mLastPredictionHorizonSecNoReset = predictionHorizonSec; 5965 5966 boolean wifiWins = mWifiWinsUsabilityScore; 5967 if (score > LOW_WIFI_USABILITY_SCORE) { 5968 wifiWins = true; 5969 } else if (score < LOW_WIFI_USABILITY_SCORE) { 5970 wifiWins = false; 5971 } 5972 5973 if (wifiWins != mWifiWinsUsabilityScore) { 5974 mWifiWinsUsabilityScore = wifiWins; 5975 StaEvent event = new StaEvent(); 5976 event.type = StaEvent.TYPE_WIFI_USABILITY_SCORE_BREACH; 5977 addStaEvent(event); 5978 // Only record the first score breach by checking whether mScoreBreachLowTimeMillis 5979 // has been set to -1 5980 if (!wifiWins && mScoreBreachLowTimeMillis == -1) { 5981 mScoreBreachLowTimeMillis = mClock.getElapsedSinceBootMillis(); 5982 } 5983 } 5984 } 5985 } 5986 5987 /** 5988 * Reports stats for a successful link probe. 5989 * 5990 * @param timeSinceLastTxSuccessMs At {@code startTimestampMs}, the number of milliseconds since 5991 * the last Tx success (according to 5992 * {@link WifiInfo#txSuccess}). 5993 * @param rssi The Rx RSSI at {@code startTimestampMs}. 5994 * @param linkSpeed The Tx link speed in Mbps at {@code startTimestampMs}. 5995 * @param elapsedTimeMs The number of milliseconds between when the command to transmit the 5996 * probe was sent to the driver and when the driver responded that the 5997 * probe was ACKed. Note: this number should be correlated with the number 5998 * of retries that the driver attempted before the probe was ACKed. 5999 */ 6000 public void logLinkProbeSuccess(long timeSinceLastTxSuccessMs, 6001 int rssi, int linkSpeed, int elapsedTimeMs) { 6002 synchronized (mLock) { 6003 mProbeStatusSinceLastUpdate = 6004 android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS; 6005 mProbeElapsedTimeSinceLastUpdateMs = elapsedTimeMs; 6006 6007 mLinkProbeSuccessSecondsSinceLastTxSuccessHistogram.increment( 6008 (int) (timeSinceLastTxSuccessMs / 1000)); 6009 mLinkProbeSuccessRssiCounts.increment(rssi); 6010 mLinkProbeSuccessLinkSpeedCounts.increment(linkSpeed); 6011 mLinkProbeSuccessElapsedTimeMsHistogram.increment(elapsedTimeMs); 6012 6013 if (mLinkProbeStaEventCount < MAX_LINK_PROBE_STA_EVENTS) { 6014 StaEvent event = new StaEvent(); 6015 event.type = StaEvent.TYPE_LINK_PROBE; 6016 event.linkProbeWasSuccess = true; 6017 event.linkProbeSuccessElapsedTimeMs = elapsedTimeMs; 6018 addStaEvent(event); 6019 } 6020 mLinkProbeStaEventCount++; 6021 } 6022 } 6023 6024 /** 6025 * Reports stats for an unsuccessful link probe. 6026 * 6027 * @param timeSinceLastTxSuccessMs At {@code startTimestampMs}, the number of milliseconds since 6028 * the last Tx success (according to 6029 * {@link WifiInfo#txSuccess}). 6030 * @param rssi The Rx RSSI at {@code startTimestampMs}. 6031 * @param linkSpeed The Tx link speed in Mbps at {@code startTimestampMs}. 6032 * @param reason The error code for the failure. See 6033 * {@link WifiNl80211Manager.SendMgmtFrameError}. 6034 */ 6035 public void logLinkProbeFailure(long timeSinceLastTxSuccessMs, 6036 int rssi, int linkSpeed, int reason) { 6037 synchronized (mLock) { 6038 mProbeStatusSinceLastUpdate = 6039 android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE; 6040 mProbeElapsedTimeSinceLastUpdateMs = Integer.MAX_VALUE; 6041 6042 mLinkProbeFailureSecondsSinceLastTxSuccessHistogram.increment( 6043 (int) (timeSinceLastTxSuccessMs / 1000)); 6044 mLinkProbeFailureRssiCounts.increment(rssi); 6045 mLinkProbeFailureLinkSpeedCounts.increment(linkSpeed); 6046 mLinkProbeFailureReasonCounts.increment(reason); 6047 6048 if (mLinkProbeStaEventCount < MAX_LINK_PROBE_STA_EVENTS) { 6049 StaEvent event = new StaEvent(); 6050 event.type = StaEvent.TYPE_LINK_PROBE; 6051 event.linkProbeWasSuccess = false; 6052 event.linkProbeFailureReason = linkProbeFailureReasonToProto(reason); 6053 addStaEvent(event); 6054 } 6055 mLinkProbeStaEventCount++; 6056 } 6057 } 6058 6059 /** 6060 * Increments the number of probes triggered by the experiment `experimentId`. 6061 */ 6062 public void incrementLinkProbeExperimentProbeCount(String experimentId) { 6063 synchronized (mLock) { 6064 mLinkProbeExperimentProbeCounts.increment(experimentId); 6065 } 6066 } 6067 6068 /** 6069 * Update wifi config store read duration. 6070 * 6071 * @param timeMs Time it took to complete the operation, in milliseconds 6072 */ 6073 public void noteWifiConfigStoreReadDuration(int timeMs) { 6074 synchronized (mLock) { 6075 MetricsUtils.addValueToLinearHistogram(timeMs, mWifiConfigStoreReadDurationHistogram, 6076 WIFI_CONFIG_STORE_IO_DURATION_BUCKET_RANGES_MS); 6077 } 6078 } 6079 6080 /** 6081 * Update wifi config store write duration. 6082 * 6083 * @param timeMs Time it took to complete the operation, in milliseconds 6084 */ 6085 public void noteWifiConfigStoreWriteDuration(int timeMs) { 6086 synchronized (mLock) { 6087 MetricsUtils.addValueToLinearHistogram(timeMs, mWifiConfigStoreWriteDurationHistogram, 6088 WIFI_CONFIG_STORE_IO_DURATION_BUCKET_RANGES_MS); 6089 } 6090 } 6091 6092 /** 6093 * Logs the decision of a network selection algorithm when compared against another network 6094 * selection algorithm. 6095 * 6096 * @param experiment1Id ID of one experiment 6097 * @param experiment2Id ID of the other experiment 6098 * @param isSameDecision did the 2 experiments make the same decision? 6099 * @param numNetworkChoices the number of non-null network choices there were, where the null 6100 * choice is not selecting any network 6101 */ 6102 public void logNetworkSelectionDecision(int experiment1Id, int experiment2Id, 6103 boolean isSameDecision, int numNetworkChoices) { 6104 if (numNetworkChoices < 0) { 6105 Log.e(TAG, "numNetworkChoices cannot be negative!"); 6106 return; 6107 } 6108 if (experiment1Id == experiment2Id) { 6109 Log.e(TAG, "comparing the same experiment id: " + experiment1Id); 6110 return; 6111 } 6112 6113 Pair<Integer, Integer> key = new Pair<>(experiment1Id, experiment2Id); 6114 synchronized (mLock) { 6115 NetworkSelectionExperimentResults results = 6116 mNetworkSelectionExperimentPairNumChoicesCounts 6117 .computeIfAbsent(key, k -> new NetworkSelectionExperimentResults()); 6118 6119 IntCounter counter = isSameDecision 6120 ? results.sameSelectionNumChoicesCounter 6121 : results.differentSelectionNumChoicesCounter; 6122 6123 counter.increment(numNetworkChoices); 6124 } 6125 } 6126 6127 /** Increment number of network request API usage stats */ 6128 public void incrementNetworkRequestApiNumRequest() { 6129 synchronized (mLock) { 6130 mWifiNetworkRequestApiLog.numRequest++; 6131 } 6132 } 6133 6134 /** Add to the network request API match size histogram */ 6135 public void incrementNetworkRequestApiMatchSizeHistogram(int matchSize) { 6136 synchronized (mLock) { 6137 mWifiNetworkRequestApiMatchSizeHistogram.increment(matchSize); 6138 } 6139 } 6140 6141 /** Increment number of connection success via network request API */ 6142 public void incrementNetworkRequestApiNumConnectSuccess() { 6143 synchronized (mLock) { 6144 mWifiNetworkRequestApiLog.numConnectSuccess++; 6145 } 6146 } 6147 6148 /** Increment number of requests that bypassed user approval via network request API */ 6149 public void incrementNetworkRequestApiNumUserApprovalBypass() { 6150 synchronized (mLock) { 6151 mWifiNetworkRequestApiLog.numUserApprovalBypass++; 6152 } 6153 } 6154 6155 /** Increment number of requests that user rejected via network request API */ 6156 public void incrementNetworkRequestApiNumUserReject() { 6157 synchronized (mLock) { 6158 mWifiNetworkRequestApiLog.numUserReject++; 6159 } 6160 } 6161 6162 /** Increment number of requests from unique apps via network request API */ 6163 public void incrementNetworkRequestApiNumApps() { 6164 synchronized (mLock) { 6165 mWifiNetworkRequestApiLog.numApps++; 6166 } 6167 } 6168 6169 /** Increment number of network suggestion API modification by app stats */ 6170 public void incrementNetworkSuggestionApiNumModification() { 6171 synchronized (mLock) { 6172 mWifiNetworkSuggestionApiLog.numModification++; 6173 } 6174 } 6175 6176 /** Increment number of connection success via network suggestion API */ 6177 public void incrementNetworkSuggestionApiNumConnectSuccess() { 6178 synchronized (mLock) { 6179 mWifiNetworkSuggestionApiLog.numConnectSuccess++; 6180 } 6181 } 6182 6183 /** Increment number of connection failure via network suggestion API */ 6184 public void incrementNetworkSuggestionApiNumConnectFailure() { 6185 synchronized (mLock) { 6186 mWifiNetworkSuggestionApiLog.numConnectFailure++; 6187 } 6188 } 6189 6190 /** Increment number of user revoke suggestion permission. Including from settings or 6191 * disallowed from UI. 6192 */ 6193 public void incrementNetworkSuggestionUserRevokePermission() { 6194 synchronized (mLock) { 6195 mWifiNetworkSuggestionApiLog.userRevokeAppSuggestionPermission++; 6196 } 6197 } 6198 6199 /** Clear and set the latest network suggestion API max list size histogram */ 6200 public void noteNetworkSuggestionApiListSizeHistogram(List<Integer> listSizes) { 6201 synchronized (mLock) { 6202 mWifiNetworkSuggestionApiListSizeHistogram.clear(); 6203 for (Integer listSize : listSizes) { 6204 mWifiNetworkSuggestionApiListSizeHistogram.increment(listSize); 6205 } 6206 } 6207 } 6208 6209 /** Increment number of app add suggestion with different privilege */ 6210 public void incrementNetworkSuggestionApiUsageNumOfAppInType(int appType) { 6211 int typeCode; 6212 synchronized (mLock) { 6213 switch (appType) { 6214 case WifiNetworkSuggestionsManager.APP_TYPE_CARRIER_PRIVILEGED: 6215 typeCode = WifiNetworkSuggestionApiLog.TYPE_CARRIER_PRIVILEGED; 6216 break; 6217 case WifiNetworkSuggestionsManager.APP_TYPE_NETWORK_PROVISIONING: 6218 typeCode = WifiNetworkSuggestionApiLog.TYPE_NETWORK_PROVISIONING; 6219 break; 6220 case WifiNetworkSuggestionsManager.APP_TYPE_NON_PRIVILEGED: 6221 typeCode = WifiNetworkSuggestionApiLog.TYPE_NON_PRIVILEGED; 6222 break; 6223 default: 6224 typeCode = WifiNetworkSuggestionApiLog.TYPE_UNKNOWN; 6225 } 6226 mWifiNetworkSuggestionApiAppTypeCounter.increment(typeCode); 6227 } 6228 } 6229 6230 /** Add user action to the approval suggestion app UI */ 6231 public void addUserApprovalSuggestionAppUiReaction(@WifiNetworkSuggestionsManager.UserActionCode 6232 int actionType, boolean isDialog) { 6233 int actionCode; 6234 switch (actionType) { 6235 case WifiNetworkSuggestionsManager.ACTION_USER_ALLOWED_APP: 6236 actionCode = UserReactionToApprovalUiEvent.ACTION_ALLOWED; 6237 break; 6238 case WifiNetworkSuggestionsManager.ACTION_USER_DISALLOWED_APP: 6239 actionCode = UserReactionToApprovalUiEvent.ACTION_DISALLOWED; 6240 break; 6241 case WifiNetworkSuggestionsManager.ACTION_USER_DISMISS: 6242 actionCode = UserReactionToApprovalUiEvent.ACTION_DISMISS; 6243 break; 6244 default: 6245 actionCode = UserReactionToApprovalUiEvent.ACTION_UNKNOWN; 6246 } 6247 UserReaction event = new UserReaction(); 6248 event.userAction = actionCode; 6249 event.isDialog = isDialog; 6250 synchronized (mLock) { 6251 mUserApprovalSuggestionAppUiReactionList.add(event); 6252 } 6253 } 6254 6255 /** Add user action to the approval Carrier Imsi protection exemption UI */ 6256 public void addUserApprovalCarrierUiReaction(@WifiCarrierInfoManager.UserActionCode 6257 int actionType, boolean isDialog) { 6258 int actionCode; 6259 switch (actionType) { 6260 case WifiCarrierInfoManager.ACTION_USER_ALLOWED_CARRIER: 6261 actionCode = UserReactionToApprovalUiEvent.ACTION_ALLOWED; 6262 break; 6263 case WifiCarrierInfoManager.ACTION_USER_DISALLOWED_CARRIER: 6264 actionCode = UserReactionToApprovalUiEvent.ACTION_DISALLOWED; 6265 break; 6266 case WifiCarrierInfoManager.ACTION_USER_DISMISS: 6267 actionCode = UserReactionToApprovalUiEvent.ACTION_DISMISS; 6268 break; 6269 default: 6270 actionCode = UserReactionToApprovalUiEvent.ACTION_UNKNOWN; 6271 } 6272 UserReaction event = new UserReaction(); 6273 event.userAction = actionCode; 6274 event.isDialog = isDialog; 6275 6276 synchronized (mLock) { 6277 mUserApprovalCarrierUiReactionList.add(event); 6278 } 6279 } 6280 6281 /** 6282 * Sets the nominator for a network (i.e. which entity made the suggestion to connect) 6283 * @param networkId the ID of the network, from its {@link WifiConfiguration} 6284 * @param nominatorId the entity that made the suggestion to connect to this network, 6285 * from {@link WifiMetricsProto.ConnectionEvent.ConnectionNominator} 6286 */ 6287 public void setNominatorForNetwork(int networkId, int nominatorId) { 6288 synchronized (mLock) { 6289 if (networkId == WifiConfiguration.INVALID_NETWORK_ID) return; 6290 mNetworkIdToNominatorId.put(networkId, nominatorId); 6291 6292 // user connect choice is preventing switcing off from the connected network 6293 if (nominatorId 6294 == WifiMetricsProto.ConnectionEvent.NOMINATOR_SAVED_USER_CONNECT_CHOICE 6295 && mWifiStatusBuilder.getNetworkId() == networkId) { 6296 mWifiStatusBuilder.setUserChoice(true); 6297 } 6298 } 6299 } 6300 6301 /** 6302 * Sets the numeric CandidateScorer id. 6303 */ 6304 public void setNetworkSelectorExperimentId(int expId) { 6305 synchronized (mLock) { 6306 mNetworkSelectorExperimentId = expId; 6307 } 6308 } 6309 6310 /** Add a WifiLock acqusition session */ 6311 public void addWifiLockAcqSession(int lockType, long duration) { 6312 switch (lockType) { 6313 case WifiManager.WIFI_MODE_FULL_HIGH_PERF: 6314 mWifiLockHighPerfAcqDurationSecHistogram.increment((int) (duration / 1000)); 6315 break; 6316 6317 case WifiManager.WIFI_MODE_FULL_LOW_LATENCY: 6318 mWifiLockLowLatencyAcqDurationSecHistogram.increment((int) (duration / 1000)); 6319 break; 6320 6321 default: 6322 Log.e(TAG, "addWifiLockAcqSession: Invalid lock type: " + lockType); 6323 break; 6324 } 6325 } 6326 6327 /** Add a WifiLock active session */ 6328 public void addWifiLockActiveSession(int lockType, long duration) { 6329 switch (lockType) { 6330 case WifiManager.WIFI_MODE_FULL_HIGH_PERF: 6331 mWifiLockStats.highPerfActiveTimeMs += duration; 6332 mWifiLockHighPerfActiveSessionDurationSecHistogram.increment( 6333 (int) (duration / 1000)); 6334 break; 6335 6336 case WifiManager.WIFI_MODE_FULL_LOW_LATENCY: 6337 mWifiLockStats.lowLatencyActiveTimeMs += duration; 6338 mWifiLockLowLatencyActiveSessionDurationSecHistogram.increment( 6339 (int) (duration / 1000)); 6340 break; 6341 6342 default: 6343 Log.e(TAG, "addWifiLockActiveSession: Invalid lock type: " + lockType); 6344 break; 6345 } 6346 } 6347 6348 /** Increments metrics counting number of addOrUpdateNetwork calls. **/ 6349 public void incrementNumAddOrUpdateNetworkCalls() { 6350 synchronized (mLock) { 6351 mWifiLogProto.numAddOrUpdateNetworkCalls++; 6352 } 6353 } 6354 6355 /** Increments metrics counting number of enableNetwork calls. **/ 6356 public void incrementNumEnableNetworkCalls() { 6357 synchronized (mLock) { 6358 mWifiLogProto.numEnableNetworkCalls++; 6359 } 6360 } 6361 6362 /** Add to WifiToggleStats **/ 6363 public void incrementNumWifiToggles(boolean isPrivileged, boolean enable) { 6364 synchronized (mLock) { 6365 if (isPrivileged && enable) { 6366 mWifiToggleStats.numToggleOnPrivileged++; 6367 } else if (isPrivileged && !enable) { 6368 mWifiToggleStats.numToggleOffPrivileged++; 6369 } else if (!isPrivileged && enable) { 6370 mWifiToggleStats.numToggleOnNormal++; 6371 } else { 6372 mWifiToggleStats.numToggleOffNormal++; 6373 } 6374 } 6375 } 6376 6377 /** 6378 * Increment number of passpoint provision failure 6379 * @param failureCode indicates error condition 6380 */ 6381 public void incrementPasspointProvisionFailure(int failureCode) { 6382 int provisionFailureCode; 6383 synchronized (mLock) { 6384 switch (failureCode) { 6385 case ProvisioningCallback.OSU_FAILURE_AP_CONNECTION: 6386 provisionFailureCode = PasspointProvisionStats.OSU_FAILURE_AP_CONNECTION; 6387 break; 6388 case ProvisioningCallback.OSU_FAILURE_SERVER_URL_INVALID: 6389 provisionFailureCode = PasspointProvisionStats.OSU_FAILURE_SERVER_URL_INVALID; 6390 break; 6391 case ProvisioningCallback.OSU_FAILURE_SERVER_CONNECTION: 6392 provisionFailureCode = PasspointProvisionStats.OSU_FAILURE_SERVER_CONNECTION; 6393 break; 6394 case ProvisioningCallback.OSU_FAILURE_SERVER_VALIDATION: 6395 provisionFailureCode = PasspointProvisionStats.OSU_FAILURE_SERVER_VALIDATION; 6396 break; 6397 case ProvisioningCallback.OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION: 6398 provisionFailureCode = PasspointProvisionStats 6399 .OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION; 6400 break; 6401 case ProvisioningCallback.OSU_FAILURE_PROVISIONING_ABORTED: 6402 provisionFailureCode = PasspointProvisionStats.OSU_FAILURE_PROVISIONING_ABORTED; 6403 break; 6404 case ProvisioningCallback.OSU_FAILURE_PROVISIONING_NOT_AVAILABLE: 6405 provisionFailureCode = PasspointProvisionStats 6406 .OSU_FAILURE_PROVISIONING_NOT_AVAILABLE; 6407 break; 6408 case ProvisioningCallback.OSU_FAILURE_INVALID_URL_FORMAT_FOR_OSU: 6409 provisionFailureCode = PasspointProvisionStats 6410 .OSU_FAILURE_INVALID_URL_FORMAT_FOR_OSU; 6411 break; 6412 case ProvisioningCallback.OSU_FAILURE_UNEXPECTED_COMMAND_TYPE: 6413 provisionFailureCode = PasspointProvisionStats 6414 .OSU_FAILURE_UNEXPECTED_COMMAND_TYPE; 6415 break; 6416 case ProvisioningCallback.OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_TYPE: 6417 provisionFailureCode = PasspointProvisionStats 6418 .OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_TYPE; 6419 break; 6420 case ProvisioningCallback.OSU_FAILURE_SOAP_MESSAGE_EXCHANGE: 6421 provisionFailureCode = PasspointProvisionStats 6422 .OSU_FAILURE_SOAP_MESSAGE_EXCHANGE; 6423 break; 6424 case ProvisioningCallback.OSU_FAILURE_START_REDIRECT_LISTENER: 6425 provisionFailureCode = PasspointProvisionStats 6426 .OSU_FAILURE_START_REDIRECT_LISTENER; 6427 break; 6428 case ProvisioningCallback.OSU_FAILURE_TIMED_OUT_REDIRECT_LISTENER: 6429 provisionFailureCode = PasspointProvisionStats 6430 .OSU_FAILURE_TIMED_OUT_REDIRECT_LISTENER; 6431 break; 6432 case ProvisioningCallback.OSU_FAILURE_NO_OSU_ACTIVITY_FOUND: 6433 provisionFailureCode = PasspointProvisionStats 6434 .OSU_FAILURE_NO_OSU_ACTIVITY_FOUND; 6435 break; 6436 case ProvisioningCallback.OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_STATUS: 6437 provisionFailureCode = PasspointProvisionStats 6438 .OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_STATUS; 6439 break; 6440 case ProvisioningCallback.OSU_FAILURE_NO_PPS_MO: 6441 provisionFailureCode = PasspointProvisionStats.OSU_FAILURE_NO_PPS_MO; 6442 break; 6443 case ProvisioningCallback.OSU_FAILURE_NO_AAA_SERVER_TRUST_ROOT_NODE: 6444 provisionFailureCode = PasspointProvisionStats 6445 .OSU_FAILURE_NO_AAA_SERVER_TRUST_ROOT_NODE; 6446 break; 6447 case ProvisioningCallback.OSU_FAILURE_NO_REMEDIATION_SERVER_TRUST_ROOT_NODE: 6448 provisionFailureCode = PasspointProvisionStats 6449 .OSU_FAILURE_NO_REMEDIATION_SERVER_TRUST_ROOT_NODE; 6450 break; 6451 case ProvisioningCallback.OSU_FAILURE_NO_POLICY_SERVER_TRUST_ROOT_NODE: 6452 provisionFailureCode = PasspointProvisionStats 6453 .OSU_FAILURE_NO_POLICY_SERVER_TRUST_ROOT_NODE; 6454 break; 6455 case ProvisioningCallback.OSU_FAILURE_RETRIEVE_TRUST_ROOT_CERTIFICATES: 6456 provisionFailureCode = PasspointProvisionStats 6457 .OSU_FAILURE_RETRIEVE_TRUST_ROOT_CERTIFICATES; 6458 break; 6459 case ProvisioningCallback.OSU_FAILURE_NO_AAA_TRUST_ROOT_CERTIFICATE: 6460 provisionFailureCode = PasspointProvisionStats 6461 .OSU_FAILURE_NO_AAA_TRUST_ROOT_CERTIFICATE; 6462 break; 6463 case ProvisioningCallback.OSU_FAILURE_ADD_PASSPOINT_CONFIGURATION: 6464 provisionFailureCode = PasspointProvisionStats 6465 .OSU_FAILURE_ADD_PASSPOINT_CONFIGURATION; 6466 break; 6467 case ProvisioningCallback.OSU_FAILURE_OSU_PROVIDER_NOT_FOUND: 6468 provisionFailureCode = PasspointProvisionStats 6469 .OSU_FAILURE_OSU_PROVIDER_NOT_FOUND; 6470 break; 6471 default: 6472 provisionFailureCode = PasspointProvisionStats.OSU_FAILURE_UNKNOWN; 6473 } 6474 mPasspointProvisionFailureCounts.increment(provisionFailureCode); 6475 } 6476 } 6477 6478 /** 6479 * Add to the histogram of number of BSSIDs filtered out from network selection. 6480 */ 6481 public void incrementNetworkSelectionFilteredBssidCount(int numBssid) { 6482 mBssidBlocklistStats.networkSelectionFilteredBssidCount.increment(numBssid); 6483 } 6484 6485 /** 6486 * Increment the number of network connections skipped due to the high movement feature. 6487 */ 6488 public void incrementNumHighMovementConnectionSkipped() { 6489 mBssidBlocklistStats.numHighMovementConnectionSkipped++; 6490 } 6491 6492 /** 6493 * Increment the number of network connections initiated while under the high movement 6494 * feature. 6495 */ 6496 public void incrementNumHighMovementConnectionStarted() { 6497 mBssidBlocklistStats.numHighMovementConnectionStarted++; 6498 } 6499 6500 /** 6501 * Increment number of passpoint provision success 6502 */ 6503 public void incrementPasspointProvisionSuccess() { 6504 synchronized (mLock) { 6505 mNumProvisionSuccess++; 6506 } 6507 } 6508 6509 /** 6510 * Increment number of IP renewal failures. 6511 */ 6512 public void incrementIpRenewalFailure() { 6513 synchronized (mLock) { 6514 mWifiLogProto.numIpRenewalFailure++; 6515 } 6516 } 6517 6518 /** 6519 * Sets the duration for evaluating Wifi condition to trigger a data stall 6520 */ 6521 public void setDataStallDurationMs(int duration) { 6522 synchronized (mLock) { 6523 mExperimentValues.dataStallDurationMs = duration; 6524 } 6525 } 6526 6527 /** 6528 * Sets the threshold of Tx throughput below which to trigger a data stall 6529 */ 6530 public void setDataStallTxTputThrKbps(int txTputThr) { 6531 synchronized (mLock) { 6532 mExperimentValues.dataStallTxTputThrKbps = txTputThr; 6533 } 6534 } 6535 6536 /** 6537 * Sets the threshold of Rx throughput below which to trigger a data stall 6538 */ 6539 public void setDataStallRxTputThrKbps(int rxTputThr) { 6540 synchronized (mLock) { 6541 mExperimentValues.dataStallRxTputThrKbps = rxTputThr; 6542 } 6543 } 6544 6545 /** 6546 * Sets the threshold of Tx packet error rate above which to trigger a data stall 6547 */ 6548 public void setDataStallTxPerThr(int txPerThr) { 6549 synchronized (mLock) { 6550 mExperimentValues.dataStallTxPerThr = txPerThr; 6551 } 6552 } 6553 6554 /** 6555 * Sets the threshold of CCA level above which to trigger a data stall 6556 */ 6557 public void setDataStallCcaLevelThr(int ccaLevel) { 6558 synchronized (mLock) { 6559 mExperimentValues.dataStallCcaLevelThr = ccaLevel; 6560 } 6561 } 6562 6563 /** 6564 * Sets health monitor RSSI poll valid time in ms 6565 */ 6566 public void setHealthMonitorRssiPollValidTimeMs(int rssiPollValidTimeMs) { 6567 synchronized (mLock) { 6568 mExperimentValues.healthMonitorRssiPollValidTimeMs = rssiPollValidTimeMs; 6569 } 6570 } 6571 6572 /** 6573 * Increment connection duration while link layer stats report are on 6574 */ 6575 public void incrementConnectionDuration(int timeDeltaLastTwoPollsMs, 6576 boolean isThroughputSufficient, boolean isCellularDataAvailable) { 6577 synchronized (mLock) { 6578 mConnectionDurationStats.incrementDurationCount(timeDeltaLastTwoPollsMs, 6579 isThroughputSufficient, isCellularDataAvailable); 6580 } 6581 } 6582 6583 /** 6584 * Sets the status to indicate whether external WiFi connected network scorer is present or not. 6585 */ 6586 public void setIsExternalWifiScorerOn(boolean value) { 6587 synchronized (mLock) { 6588 mWifiLogProto.isExternalWifiScorerOn = value; 6589 } 6590 } 6591 6592 /** 6593 * Note Wi-Fi off metrics 6594 */ 6595 public void noteWifiOff(boolean isDeferred, boolean isTimeout, int duration) { 6596 synchronized (mLock) { 6597 mWifiOffMetrics.numWifiOff++; 6598 if (isDeferred) { 6599 mWifiOffMetrics.numWifiOffDeferring++; 6600 if (isTimeout) { 6601 mWifiOffMetrics.numWifiOffDeferringTimeout++; 6602 } 6603 mWifiOffMetrics.wifiOffDeferringTimeHistogram.increment(duration); 6604 } 6605 } 6606 } 6607 6608 /** 6609 * Increment number of BSSIDs filtered out from network selection due to MBO Association 6610 * disallowed indication. 6611 */ 6612 public void incrementNetworkSelectionFilteredBssidCountDueToMboAssocDisallowInd() { 6613 synchronized (mLock) { 6614 mWifiLogProto.numBssidFilteredDueToMboAssocDisallowInd++; 6615 } 6616 } 6617 6618 /** 6619 * Increment number of times force scan is triggered due to a 6620 * BSS transition management request frame from AP. 6621 */ 6622 public void incrementForceScanCountDueToSteeringRequest() { 6623 synchronized (mLock) { 6624 mWifiLogProto.numForceScanDueToSteeringRequest++; 6625 } 6626 } 6627 6628 /** 6629 * Increment number of times STA received cellular switch 6630 * request from MBO supported AP. 6631 */ 6632 public void incrementMboCellularSwitchRequestCount() { 6633 synchronized (mLock) { 6634 mWifiLogProto.numMboCellularSwitchRequest++; 6635 } 6636 } 6637 6638 /** 6639 * Increment number of times STA received steering request 6640 * including MBO association retry delay. 6641 */ 6642 public void incrementSteeringRequestCountIncludingMboAssocRetryDelay() { 6643 synchronized (mLock) { 6644 mWifiLogProto.numSteeringRequestIncludingMboAssocRetryDelay++; 6645 } 6646 } 6647 6648 /** 6649 * Increment number of connect request to AP adding FILS AKM. 6650 */ 6651 public void incrementConnectRequestWithFilsAkmCount() { 6652 synchronized (mLock) { 6653 mWifiLogProto.numConnectRequestWithFilsAkm++; 6654 } 6655 } 6656 6657 /** 6658 * Increment number of times STA connected through FILS 6659 * authentication. 6660 */ 6661 public void incrementL2ConnectionThroughFilsAuthCount() { 6662 synchronized (mLock) { 6663 mWifiLogProto.numL2ConnectionThroughFilsAuthentication++; 6664 } 6665 } 6666 6667 /** 6668 * Note SoftapConfig Reset Metrics 6669 */ 6670 public void noteSoftApConfigReset(SoftApConfiguration originalConfig, 6671 SoftApConfiguration newConfig) { 6672 synchronized (mLock) { 6673 if (originalConfig.getSecurityType() != newConfig.getSecurityType()) { 6674 mSoftApConfigLimitationMetrics.numSecurityTypeResetToDefault++; 6675 } 6676 if (originalConfig.getMaxNumberOfClients() != newConfig.getMaxNumberOfClients()) { 6677 mSoftApConfigLimitationMetrics.numMaxClientSettingResetToDefault++; 6678 } 6679 if (originalConfig.isClientControlByUserEnabled() 6680 != newConfig.isClientControlByUserEnabled()) { 6681 mSoftApConfigLimitationMetrics.numClientControlByUserResetToDefault++; 6682 } 6683 } 6684 } 6685 6686 /** 6687 * Note Softap client blocked due to max client limitation 6688 */ 6689 public void noteSoftApClientBlocked(int maxClient) { 6690 mSoftApConfigLimitationMetrics.maxClientSettingWhenReachHistogram.increment(maxClient); 6691 } 6692 6693 /** 6694 * Increment number of connection with different BSSID between framework and firmware selection. 6695 */ 6696 public void incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware() { 6697 synchronized (mLock) { 6698 mWifiLogProto.numBssidDifferentSelectionBetweenFrameworkAndFirmware++; 6699 } 6700 } 6701 6702 /** 6703 * Note the carrier wifi network connected successfully. 6704 */ 6705 public void incrementNumOfCarrierWifiConnectionSuccess() { 6706 synchronized (mLock) { 6707 mCarrierWifiMetrics.numConnectionSuccess++; 6708 } 6709 } 6710 6711 /** 6712 * Note the carrier wifi network connection authentication failure. 6713 */ 6714 public void incrementNumOfCarrierWifiConnectionAuthFailure() { 6715 synchronized (mLock) { 6716 mCarrierWifiMetrics.numConnectionAuthFailure++; 6717 } 6718 } 6719 6720 /** 6721 * Note the carrier wifi network connection non-authentication failure. 6722 */ 6723 public void incrementNumOfCarrierWifiConnectionNonAuthFailure() { 6724 synchronized (mLock) { 6725 mCarrierWifiMetrics.numConnectionNonAuthFailure++; 6726 } 6727 } 6728 6729 /** 6730 * Set Adaptive Connectivity state (On/Off) 6731 */ 6732 public void setAdaptiveConnectivityState(boolean adaptiveConnectivityEnabled) { 6733 synchronized (mLock) { 6734 mAdaptiveConnectivityEnabled = adaptiveConnectivityEnabled; 6735 } 6736 } 6737 } 6738