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