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