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