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