1 /* 2 * Copyright (C) 2017 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.aware; 18 19 import static android.net.wifi.aware.WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB; 20 import static android.net.wifi.aware.WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_IB_ANY_PEER; 21 import static android.net.wifi.aware.WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB; 22 import static android.net.wifi.aware.WifiAwareNetworkSpecifier.NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER; 23 24 import android.net.wifi.aware.WifiAwareManager; 25 import android.net.wifi.aware.WifiAwareNetworkSpecifier; 26 import android.text.TextUtils; 27 import android.util.Log; 28 import android.util.SparseArray; 29 import android.util.SparseIntArray; 30 import android.util.SparseLongArray; 31 32 import com.android.internal.annotations.VisibleForTesting; 33 import com.android.server.wifi.Clock; 34 import com.android.server.wifi.hal.WifiNanIface.NanStatusCode; 35 import com.android.server.wifi.proto.WifiStatsLog; 36 import com.android.server.wifi.proto.nano.WifiMetricsProto; 37 import com.android.server.wifi.util.MetricsUtils; 38 39 import java.io.FileDescriptor; 40 import java.io.PrintWriter; 41 import java.util.Collections; 42 import java.util.HashMap; 43 import java.util.HashSet; 44 import java.util.Map; 45 import java.util.Set; 46 47 /** 48 * Wi-Fi Aware metric container/processor. 49 */ 50 public class WifiAwareMetrics { 51 private static final String TAG = "WifiAwareMetrics"; 52 53 // Histogram: 8 buckets (i=0, ..., 7) of 9 slots in range 10^i -> 10^(i+1) 54 // Buckets: 55 // 1 -> 10: 9 @ 1 56 // 10 -> 100: 9 @ 10 57 // 100 -> 1000: 9 @ 10^2 58 // 10^3 -> 10^4: 9 @ 10^3 59 // 10^4 -> 10^5: 9 @ 10^4 60 // 10^5 -> 10^6: 9 @ 10^5 61 // 10^6 -> 10^7: 9 @ 10^6 62 // 10^7 -> 10^8: 9 @ 10^7 --> 10^8 ms -> 10^5s -> 28 hours 63 private static final MetricsUtils.LogHistParms DURATION_LOG_HISTOGRAM = 64 new MetricsUtils.LogHistParms(0, 1, 10, 9, 8); 65 66 // Histogram for ranging limits in discovery. Indicates the following 5 buckets (in meters): 67 // < 10 68 // [10, 30) 69 // [30, 60) 70 // [60, 100) 71 // >= 100 72 private static final int[] RANGING_LIMIT_METERS = { 10, 30, 60, 100 }; 73 74 private static final int INVALID_SESSION_ID = -1; 75 76 private final Object mLock = new Object(); 77 private final Clock mClock; 78 79 // enableUsage/disableUsage data 80 private long mLastEnableUsageMs = 0; 81 private long mLastEnableUsageInThisSampleWindowMs = 0; 82 private long mAvailableTimeMs = 0; 83 private SparseIntArray mHistogramAwareAvailableDurationMs = new SparseIntArray(); 84 85 // enabled data 86 private long mLastEnableAwareMs = 0; 87 private long mLastEnableAwareInThisSampleWindowMs = 0; 88 private long mEnabledTimeMs = 0; 89 private SparseIntArray mHistogramAwareEnabledDurationMs = new SparseIntArray(); 90 91 // attach data 92 private static class AttachData { 93 boolean mUsesIdentityCallback; // do any attach sessions of the UID use identity callback 94 int mMaxConcurrentAttaches; 95 } 96 private Map<Integer, AttachData> mAttachDataByUid = new HashMap<>(); 97 private SparseIntArray mAttachStatusData = new SparseIntArray(); 98 private SparseIntArray mHistogramAttachDuration = new SparseIntArray(); 99 100 // discovery data 101 private int mMaxPublishInApp = 0; 102 private int mMaxSubscribeInApp = 0; 103 private int mMaxDiscoveryInApp = 0; 104 private int mMaxPublishInSystem = 0; 105 private int mMaxSubscribeInSystem = 0; 106 private int mMaxDiscoveryInSystem = 0; 107 private SparseIntArray mPublishStatusData = new SparseIntArray(); 108 private SparseIntArray mSubscribeStatusData = new SparseIntArray(); 109 private SparseIntArray mHistogramPublishDuration = new SparseIntArray(); 110 private SparseIntArray mHistogramSubscribeDuration = new SparseIntArray(); 111 private Set<Integer> mAppsWithDiscoverySessionResourceFailure = new HashSet<>(); 112 113 // discovery with ranging data 114 private int mMaxPublishWithRangingInApp = 0; 115 private int mMaxSubscribeWithRangingInApp = 0; 116 private int mMaxPublishWithRangingInSystem = 0; 117 private int mMaxSubscribeWithRangingInSystem = 0; 118 private SparseIntArray mHistogramSubscribeGeofenceMin = new SparseIntArray(); 119 private SparseIntArray mHistogramSubscribeGeofenceMax = new SparseIntArray(); 120 private int mNumSubscribesWithRanging = 0; 121 private int mNumMatchesWithRanging = 0; 122 private int mNumMatchesWithoutRangingForRangingEnabledSubscribes = 0; 123 124 // data-path (NDI/NDP) data 125 private int mMaxNdiInApp = 0; 126 private int mMaxNdpInApp = 0; 127 private int mMaxSecureNdpInApp = 0; 128 private int mMaxNdiInSystem = 0; 129 private int mMaxNdpInSystem = 0; 130 private int mMaxSecureNdpInSystem = 0; 131 private int mMaxNdpPerNdi = 0; 132 private SparseIntArray mInBandNdpStatusData = new SparseIntArray(); 133 private SparseIntArray mOutOfBandNdpStatusData = new SparseIntArray(); 134 135 private SparseIntArray mNdpCreationTimeDuration = new SparseIntArray(); 136 private long mNdpCreationTimeMin = -1; 137 private long mNdpCreationTimeMax = 0; 138 private long mNdpCreationTimeSum = 0; 139 private long mNdpCreationTimeSumSq = 0; 140 private long mNdpCreationTimeNumSamples = 0; 141 142 private final SparseIntArray mHistogramNdpDuration = new SparseIntArray(); 143 private final SparseIntArray mHistogramNdpRequestType = new SparseIntArray(); 144 private final SparseLongArray mDiscoveryStartTimeMsMap = new SparseLongArray(); 145 private final SparseIntArray mDiscoveryCallerTypeMap = new SparseIntArray(); 146 private final SparseArray<String> mDiscoveryAttributionTagMap = new SparseArray<>(); 147 private final SparseIntArray mDiscoveryUidMap = new SparseIntArray(); 148 private boolean mInstantModeEnabled; 149 WifiAwareMetrics(Clock clock)150 public WifiAwareMetrics(Clock clock) { 151 mClock = clock; 152 } 153 154 /** 155 * Push usage stats for WifiAwareStateMachine.enableUsage() to 156 * histogram_aware_available_duration_ms. 157 */ recordEnableUsage()158 public void recordEnableUsage() { 159 synchronized (mLock) { 160 if (mLastEnableUsageMs != 0) { 161 Log.w(TAG, "enableUsage: mLastEnableUsage*Ms initialized!?"); 162 } 163 mLastEnableUsageMs = mClock.getElapsedSinceBootMillis(); 164 mLastEnableUsageInThisSampleWindowMs = mLastEnableUsageMs; 165 } 166 } 167 168 /** 169 * Push usage stats for WifiAwareStateMachine.disableUsage() to 170 * histogram_aware_available_duration_ms. 171 */ 172 recordDisableUsage()173 public void recordDisableUsage() { 174 synchronized (mLock) { 175 if (mLastEnableUsageMs == 0) { 176 Log.e(TAG, "disableUsage: mLastEnableUsage not initialized!?"); 177 return; 178 } 179 180 long now = mClock.getElapsedSinceBootMillis(); 181 MetricsUtils.addValueToLogHistogram(now - mLastEnableUsageMs, 182 mHistogramAwareAvailableDurationMs, DURATION_LOG_HISTOGRAM); 183 mAvailableTimeMs += now - mLastEnableUsageInThisSampleWindowMs; 184 mLastEnableUsageMs = 0; 185 mLastEnableUsageInThisSampleWindowMs = 0; 186 } 187 } 188 189 /** 190 * Push usage stats of Aware actually being enabled on-the-air: start 191 */ recordEnableAware()192 public void recordEnableAware() { 193 synchronized (mLock) { 194 if (mLastEnableAwareMs != 0) { 195 return; // already enabled 196 } 197 mLastEnableAwareMs = mClock.getElapsedSinceBootMillis(); 198 mLastEnableAwareInThisSampleWindowMs = mLastEnableAwareMs; 199 } 200 } 201 202 /** 203 * Push usage stats of Aware actually being enabled on-the-air: stop (disable) 204 */ recordDisableAware()205 public void recordDisableAware() { 206 synchronized (mLock) { 207 if (mLastEnableAwareMs == 0) { 208 return; // already disabled 209 } 210 211 long now = mClock.getElapsedSinceBootMillis(); 212 MetricsUtils.addValueToLogHistogram(now - mLastEnableAwareMs, 213 mHistogramAwareEnabledDurationMs, DURATION_LOG_HISTOGRAM); 214 mEnabledTimeMs += now - mLastEnableAwareInThisSampleWindowMs; 215 mLastEnableAwareMs = 0; 216 mLastEnableAwareInThisSampleWindowMs = 0; 217 } 218 } 219 220 /** 221 * Push information about a new attach session. 222 */ recordAttachSession(int uid, boolean usesIdentityCallback, SparseArray<WifiAwareClientState> clients, int callerType, String attributionTag)223 public void recordAttachSession(int uid, boolean usesIdentityCallback, 224 SparseArray<WifiAwareClientState> clients, int callerType, String attributionTag) { 225 // count the number of clients with the specific uid 226 int currentConcurrentCount = 0; 227 for (int i = 0; i < clients.size(); ++i) { 228 if (clients.valueAt(i).getUid() == uid) { 229 ++currentConcurrentCount; 230 } 231 } 232 233 synchronized (mLock) { 234 AttachData data = mAttachDataByUid.get(uid); 235 if (data == null) { 236 data = new AttachData(); 237 mAttachDataByUid.put(uid, data); 238 } 239 data.mUsesIdentityCallback |= usesIdentityCallback; 240 data.mMaxConcurrentAttaches = Math.max(data.mMaxConcurrentAttaches, 241 currentConcurrentCount); 242 recordAttachStatus(NanStatusCode.SUCCESS, callerType, attributionTag, uid); 243 } 244 } 245 246 /** 247 * Push information about a new attach session status (recorded when attach session is created). 248 */ recordAttachStatus(int status, int callerType, String attributionTag, int uid)249 public void recordAttachStatus(int status, int callerType, String attributionTag, int uid) { 250 synchronized (mLock) { 251 addNanHalStatusToHistogram(status, mAttachStatusData); 252 WifiStatsLog.write(WifiStatsLog.WIFI_AWARE_ATTACH_REPORTED, 253 convertNanStatusCodeToWifiStatsLogEnum(status), callerType, attributionTag, 254 uid); 255 } 256 } 257 258 /** 259 * Push duration information of an attach session. 260 */ recordAttachSessionDuration(long creationTime)261 public void recordAttachSessionDuration(long creationTime) { 262 synchronized (mLock) { 263 MetricsUtils.addValueToLogHistogram(mClock.getElapsedSinceBootMillis() - creationTime, 264 mHistogramAttachDuration, DURATION_LOG_HISTOGRAM); 265 } 266 } 267 268 /** 269 * Push information about the new discovery session. 270 */ recordDiscoverySession(int uid, SparseArray<WifiAwareClientState> clients)271 public void recordDiscoverySession(int uid, SparseArray<WifiAwareClientState> clients) { 272 recordDiscoverySessionInternal(uid, clients, false, -1, -1); 273 } 274 275 /** 276 * Push information about the new discovery session with ranging enabled 277 */ recordDiscoverySessionWithRanging(int uid, boolean isSubscriberWithRanging, int minRange, int maxRange, SparseArray<WifiAwareClientState> clients)278 public void recordDiscoverySessionWithRanging(int uid, boolean isSubscriberWithRanging, 279 int minRange, int maxRange, SparseArray<WifiAwareClientState> clients) { 280 recordDiscoverySessionInternal(uid, clients, isSubscriberWithRanging, minRange, maxRange); 281 } 282 283 /** 284 * Internal combiner of discovery session information. 285 */ recordDiscoverySessionInternal(int uid, SparseArray<WifiAwareClientState> clients, boolean isRangingEnabledSubscriber, int minRange, int maxRange)286 private void recordDiscoverySessionInternal(int uid, SparseArray<WifiAwareClientState> clients, 287 boolean isRangingEnabledSubscriber, int minRange, int maxRange) { 288 // count the number of sessions per uid and overall 289 int numPublishesInSystem = 0; 290 int numSubscribesInSystem = 0; 291 int numPublishesOnUid = 0; 292 int numSubscribesOnUid = 0; 293 294 int numPublishesWithRangingInSystem = 0; 295 int numSubscribesWithRangingInSystem = 0; 296 int numPublishesWithRangingOnUid = 0; 297 int numSubscribesWithRangingOnUid = 0; 298 299 for (int i = 0; i < clients.size(); ++i) { 300 WifiAwareClientState client = clients.valueAt(i); 301 boolean sameUid = client.getUid() == uid; 302 303 SparseArray<WifiAwareDiscoverySessionState> sessions = client.getSessions(); 304 for (int j = 0; j < sessions.size(); ++j) { 305 WifiAwareDiscoverySessionState session = sessions.valueAt(j); 306 boolean isRangingEnabledForThisSession = session.isRangingEnabled(); 307 308 if (session.isPublishSession()) { 309 numPublishesInSystem += 1; 310 if (isRangingEnabledForThisSession) { 311 numPublishesWithRangingInSystem += 1; 312 } 313 if (sameUid) { 314 numPublishesOnUid += 1; 315 if (isRangingEnabledForThisSession) { 316 numPublishesWithRangingOnUid += 1; 317 } 318 } 319 } else { 320 numSubscribesInSystem += 1; 321 if (isRangingEnabledForThisSession) { 322 numSubscribesWithRangingInSystem += 1; 323 } 324 if (sameUid) { 325 numSubscribesOnUid += 1; 326 if (isRangingEnabledForThisSession) { 327 numSubscribesWithRangingOnUid += 1; 328 } 329 } 330 } 331 } 332 } 333 334 synchronized (mLock) { 335 mMaxPublishInApp = Math.max(mMaxPublishInApp, numPublishesOnUid); 336 mMaxSubscribeInApp = Math.max(mMaxSubscribeInApp, numSubscribesOnUid); 337 mMaxDiscoveryInApp = Math.max(mMaxDiscoveryInApp, 338 numPublishesOnUid + numSubscribesOnUid); 339 mMaxPublishInSystem = Math.max(mMaxPublishInSystem, numPublishesInSystem); 340 mMaxSubscribeInSystem = Math.max(mMaxSubscribeInSystem, numSubscribesInSystem); 341 mMaxDiscoveryInSystem = Math.max(mMaxDiscoveryInSystem, 342 numPublishesInSystem + numSubscribesInSystem); 343 344 mMaxPublishWithRangingInApp = Math.max(mMaxPublishWithRangingInApp, 345 numPublishesWithRangingOnUid); 346 mMaxSubscribeWithRangingInApp = Math.max(mMaxSubscribeWithRangingInApp, 347 numSubscribesWithRangingOnUid); 348 mMaxPublishWithRangingInSystem = Math.max(mMaxPublishWithRangingInSystem, 349 numPublishesWithRangingInSystem); 350 mMaxSubscribeWithRangingInSystem = Math.max(mMaxSubscribeWithRangingInSystem, 351 numSubscribesWithRangingInSystem); 352 if (isRangingEnabledSubscriber) { 353 mNumSubscribesWithRanging += 1; 354 } 355 356 if (minRange != -1) { 357 MetricsUtils.addValueToLinearHistogram(minRange, mHistogramSubscribeGeofenceMin, 358 RANGING_LIMIT_METERS); 359 } 360 if (maxRange != -1) { 361 MetricsUtils.addValueToLinearHistogram(maxRange, mHistogramSubscribeGeofenceMax, 362 RANGING_LIMIT_METERS); 363 } 364 } 365 } 366 367 /** 368 * Push information about a new discovery session status (recorded when the discovery session is 369 * created). 370 */ recordDiscoveryStatus(int uid, int status, boolean isPublish, int callerType, String attributionTag)371 public void recordDiscoveryStatus(int uid, int status, boolean isPublish, int callerType, 372 String attributionTag) { 373 recordDiscoveryStatus(uid, status, isPublish, INVALID_SESSION_ID, callerType, 374 attributionTag); 375 } 376 377 /** 378 * Push information about a new discovery session status with pubSubId. 379 */ recordDiscoveryStatus(int uid, int status, boolean isPublish, int sessionId, int callerType, String attributionTag)380 public void recordDiscoveryStatus(int uid, int status, boolean isPublish, int sessionId, 381 int callerType, String attributionTag) { 382 synchronized (mLock) { 383 if (isPublish) { 384 addNanHalStatusToHistogram(status, mPublishStatusData); 385 } else { 386 addNanHalStatusToHistogram(status, mSubscribeStatusData); 387 } 388 389 if (status == NanStatusCode.NO_RESOURCES_AVAILABLE) { 390 mAppsWithDiscoverySessionResourceFailure.add(uid); 391 } 392 if (sessionId != INVALID_SESSION_ID) { 393 mDiscoveryStartTimeMsMap.put(sessionId, mClock.getElapsedSinceBootMillis()); 394 mDiscoveryCallerTypeMap.put(sessionId, callerType); 395 mDiscoveryAttributionTagMap.put(sessionId, attributionTag); 396 mDiscoveryUidMap.put(sessionId, uid); 397 } 398 } 399 } 400 401 /** 402 * Push duration information of a discovery session. 403 */ recordDiscoverySessionDuration(long creationTime, boolean isPublish, int sessionId)404 public void recordDiscoverySessionDuration(long creationTime, boolean isPublish, 405 int sessionId) { 406 synchronized (mLock) { 407 MetricsUtils.addValueToLogHistogram(mClock.getElapsedSinceBootMillis() - creationTime, 408 isPublish ? mHistogramPublishDuration : mHistogramSubscribeDuration, 409 DURATION_LOG_HISTOGRAM); 410 mDiscoveryStartTimeMsMap.delete(sessionId); 411 mDiscoveryCallerTypeMap.delete(sessionId); 412 mDiscoveryAttributionTagMap.delete(sessionId); 413 mDiscoveryUidMap.delete(sessionId); 414 } 415 } 416 417 /** 418 * Reported when the instant mode state changes 419 */ reportAwareInstantModeEnabled(boolean enabled)420 public void reportAwareInstantModeEnabled(boolean enabled) { 421 mInstantModeEnabled = enabled; 422 } 423 424 /** 425 * Push information about Match indication (aka service discovered) for subscribe sessions 426 * which enabled ranging. Collect information about whether or not service discovery was 427 * triggered with ranging information or without (i.e. ranging disabled for some reason). 428 */ recordMatchIndicationForRangeEnabledSubscribe(boolean rangeProvided)429 public void recordMatchIndicationForRangeEnabledSubscribe(boolean rangeProvided) { 430 if (rangeProvided) { 431 mNumMatchesWithRanging++; 432 } else { 433 mNumMatchesWithoutRangingForRangingEnabledSubscribes++; 434 } 435 } 436 437 /** 438 * Record NDP (and by extension NDI) usage - on successful creation of an NDP. 439 */ recordNdpCreation(int uid, String packageName, Map<WifiAwareNetworkSpecifier, WifiAwareDataPathStateManager .AwareNetworkRequestInformation> networkRequestCache)440 public void recordNdpCreation(int uid, String packageName, 441 Map<WifiAwareNetworkSpecifier, WifiAwareDataPathStateManager 442 .AwareNetworkRequestInformation> networkRequestCache) { 443 int numNdpInApp = 0; 444 int numSecureNdpInApp = 0; 445 int numNdpInSystem = 0; 446 int numSecureNdpInSystem = 0; 447 448 Map<String, Integer> ndpPerNdiMap = new HashMap<>(); 449 Set<String> ndiInApp = new HashSet<>(); 450 Set<String> ndiInSystem = new HashSet<>(); 451 452 for (WifiAwareDataPathStateManager.AwareNetworkRequestInformation anri : 453 networkRequestCache.values()) { 454 if (anri.state 455 != WifiAwareDataPathStateManager.AwareNetworkRequestInformation 456 .STATE_CONFIRMED) { 457 continue; // only count completed (up-and-running) NDPs 458 } 459 460 boolean sameApp = (anri.uid == uid) && TextUtils.equals(anri.packageName, packageName); 461 boolean isSecure = anri.networkSpecifier.getWifiAwareDataPathSecurityConfig() != null; 462 463 // in-app stats 464 if (sameApp) { 465 numNdpInApp += 1; 466 if (isSecure) { 467 numSecureNdpInApp += 1; 468 } 469 470 ndiInApp.add(anri.interfaceName); 471 } 472 473 // system stats 474 numNdpInSystem += 1; 475 if (isSecure) { 476 numSecureNdpInSystem += 1; 477 } 478 479 // ndp/ndi stats 480 Integer ndpCount = ndpPerNdiMap.get(anri.interfaceName); 481 if (ndpCount == null) { 482 ndpPerNdiMap.put(anri.interfaceName, 1); 483 } else { 484 ndpPerNdiMap.put(anri.interfaceName, ndpCount + 1); 485 } 486 487 // ndi stats 488 ndiInSystem.add(anri.interfaceName); 489 } 490 491 synchronized (mLock) { 492 mMaxNdiInApp = Math.max(mMaxNdiInApp, ndiInApp.size()); 493 mMaxNdpInApp = Math.max(mMaxNdpInApp, numNdpInApp); 494 mMaxSecureNdpInApp = Math.max(mMaxSecureNdpInApp, numSecureNdpInApp); 495 mMaxNdiInSystem = Math.max(mMaxNdiInSystem, ndiInSystem.size()); 496 mMaxNdpInSystem = Math.max(mMaxNdpInSystem, numNdpInSystem); 497 mMaxSecureNdpInSystem = Math.max(mMaxSecureNdpInSystem, numSecureNdpInSystem); 498 if (ndpPerNdiMap.isEmpty()) { 499 return; 500 } 501 mMaxNdpPerNdi = Math.max(mMaxNdpPerNdi, Collections.max(ndpPerNdiMap.values())); 502 } 503 } 504 505 /** 506 * Record the completion status of NDP negotiation. There are multiple steps in NDP negotiation 507 * a failure on any aborts the process and is recorded. A success on intermediate stages is 508 * not recorded - only the final success. 509 */ recordNdpStatus(int status, boolean isOutOfBand, int role, long startTimestamp, int sessionId)510 public void recordNdpStatus(int status, boolean isOutOfBand, int role, long startTimestamp, 511 int sessionId) { 512 recordNdpStatus(status, isOutOfBand, role, startTimestamp, sessionId, 0); 513 } 514 515 /** 516 * Record the completion status of NDP negotiation with channelFreqMHz 517 */ recordNdpStatus(int status, boolean isOutOfBand, int role, long startTimestamp, int sessionId, int channelFreqMHz)518 public void recordNdpStatus(int status, boolean isOutOfBand, int role, long startTimestamp, 519 int sessionId, int channelFreqMHz) { 520 synchronized (mLock) { 521 if (isOutOfBand) { 522 addNanHalStatusToHistogram(status, mOutOfBandNdpStatusData); 523 } else { 524 addNanHalStatusToHistogram(status, mInBandNdpStatusData); 525 } 526 527 long currentTimeMs = mClock.getElapsedSinceBootMillis(); 528 long creationTime = currentTimeMs - startTimestamp; 529 int ndpLatencyMs = (int) Math.min(creationTime, Integer.MAX_VALUE); 530 531 long discoveryNdpLatencyMs = currentTimeMs - mDiscoveryStartTimeMsMap.get(sessionId, 0); 532 int discoveryNdpLatencyIntMs = (int) Math.min(discoveryNdpLatencyMs, Integer.MAX_VALUE); 533 WifiStatsLog.write(WifiStatsLog.WIFI_AWARE_NDP_REPORTED, 534 convertNdpRoleToWifiStatsLogEnum(role), isOutOfBand, 535 convertNanStatusCodeToWifiStatsLogEnum(status), 536 ndpLatencyMs, discoveryNdpLatencyIntMs, channelFreqMHz, mInstantModeEnabled, 537 mDiscoveryCallerTypeMap.get(sessionId), 538 mDiscoveryAttributionTagMap.get(sessionId), mDiscoveryUidMap.get(sessionId)); 539 if (status == NanStatusCode.SUCCESS) { 540 MetricsUtils.addValueToLogHistogram(creationTime, mNdpCreationTimeDuration, 541 DURATION_LOG_HISTOGRAM); 542 mNdpCreationTimeMin = (mNdpCreationTimeMin == -1) ? creationTime : Math.min( 543 mNdpCreationTimeMin, creationTime); 544 mNdpCreationTimeMax = Math.max(mNdpCreationTimeMax, creationTime); 545 mNdpCreationTimeSum += creationTime; 546 mNdpCreationTimeSumSq += creationTime * creationTime; 547 mNdpCreationTimeNumSamples += 1; 548 } 549 } 550 } 551 552 /** 553 * Record the duration of the NDP session. The creation time is assumed to be the time at 554 * which a confirm message was received (i.e. the end of the setup negotiation). 555 */ recordNdpSessionDuration(long creationTime)556 public void recordNdpSessionDuration(long creationTime) { 557 synchronized (mLock) { 558 MetricsUtils.addValueToLogHistogram(mClock.getElapsedSinceBootMillis() - creationTime, 559 mHistogramNdpDuration, DURATION_LOG_HISTOGRAM); 560 } 561 } 562 563 /** 564 * Consolidate all metrics into the proto. 565 */ consolidateProto()566 public WifiMetricsProto.WifiAwareLog consolidateProto() { 567 WifiMetricsProto.WifiAwareLog log = new WifiMetricsProto.WifiAwareLog(); 568 long now = mClock.getElapsedSinceBootMillis(); 569 synchronized (mLock) { 570 log.histogramAwareAvailableDurationMs = histogramToProtoArray( 571 MetricsUtils.logHistogramToGenericBuckets(mHistogramAwareAvailableDurationMs, 572 DURATION_LOG_HISTOGRAM)); 573 log.availableTimeMs = mAvailableTimeMs; 574 if (mLastEnableUsageInThisSampleWindowMs != 0) { 575 log.availableTimeMs += now - mLastEnableUsageInThisSampleWindowMs; 576 } 577 578 log.histogramAwareEnabledDurationMs = histogramToProtoArray( 579 MetricsUtils.logHistogramToGenericBuckets(mHistogramAwareEnabledDurationMs, 580 DURATION_LOG_HISTOGRAM)); 581 log.enabledTimeMs = mEnabledTimeMs; 582 if (mLastEnableAwareInThisSampleWindowMs != 0) { 583 log.enabledTimeMs += now - mLastEnableAwareInThisSampleWindowMs; 584 } 585 586 log.numApps = mAttachDataByUid.size(); 587 log.numAppsUsingIdentityCallback = 0; 588 log.maxConcurrentAttachSessionsInApp = 0; 589 for (AttachData ad: mAttachDataByUid.values()) { 590 if (ad.mUsesIdentityCallback) { 591 ++log.numAppsUsingIdentityCallback; 592 } 593 log.maxConcurrentAttachSessionsInApp = Math.max( 594 log.maxConcurrentAttachSessionsInApp, ad.mMaxConcurrentAttaches); 595 } 596 log.histogramAttachSessionStatus = histogramToProtoArray(mAttachStatusData); 597 log.histogramAttachDurationMs = histogramToProtoArray( 598 MetricsUtils.logHistogramToGenericBuckets(mHistogramAttachDuration, 599 DURATION_LOG_HISTOGRAM)); 600 601 log.maxConcurrentPublishInApp = mMaxPublishInApp; 602 log.maxConcurrentSubscribeInApp = mMaxSubscribeInApp; 603 log.maxConcurrentDiscoverySessionsInApp = mMaxDiscoveryInApp; 604 log.maxConcurrentPublishInSystem = mMaxPublishInSystem; 605 log.maxConcurrentSubscribeInSystem = mMaxSubscribeInSystem; 606 log.maxConcurrentDiscoverySessionsInSystem = mMaxDiscoveryInSystem; 607 log.histogramPublishStatus = histogramToProtoArray(mPublishStatusData); 608 log.histogramSubscribeStatus = histogramToProtoArray(mSubscribeStatusData); 609 log.numAppsWithDiscoverySessionFailureOutOfResources = 610 mAppsWithDiscoverySessionResourceFailure.size(); 611 log.histogramPublishSessionDurationMs = histogramToProtoArray( 612 MetricsUtils.logHistogramToGenericBuckets(mHistogramPublishDuration, 613 DURATION_LOG_HISTOGRAM)); 614 log.histogramSubscribeSessionDurationMs = histogramToProtoArray( 615 MetricsUtils.logHistogramToGenericBuckets(mHistogramSubscribeDuration, 616 DURATION_LOG_HISTOGRAM)); 617 618 log.maxConcurrentPublishWithRangingInApp = mMaxPublishWithRangingInApp; 619 log.maxConcurrentSubscribeWithRangingInApp = mMaxSubscribeWithRangingInApp; 620 log.maxConcurrentPublishWithRangingInSystem = mMaxPublishWithRangingInSystem; 621 log.maxConcurrentSubscribeWithRangingInSystem = mMaxSubscribeWithRangingInSystem; 622 log.histogramSubscribeGeofenceMin = histogramToProtoArray( 623 MetricsUtils.linearHistogramToGenericBuckets(mHistogramSubscribeGeofenceMin, 624 RANGING_LIMIT_METERS)); 625 log.histogramSubscribeGeofenceMax = histogramToProtoArray( 626 MetricsUtils.linearHistogramToGenericBuckets(mHistogramSubscribeGeofenceMax, 627 RANGING_LIMIT_METERS)); 628 log.numSubscribesWithRanging = mNumSubscribesWithRanging; 629 log.numMatchesWithRanging = mNumMatchesWithRanging; 630 log.numMatchesWithoutRangingForRangingEnabledSubscribes = 631 mNumMatchesWithoutRangingForRangingEnabledSubscribes; 632 633 log.maxConcurrentNdiInApp = mMaxNdiInApp; 634 log.maxConcurrentNdiInSystem = mMaxNdiInSystem; 635 log.maxConcurrentNdpInApp = mMaxNdpInApp; 636 log.maxConcurrentNdpInSystem = mMaxNdpInSystem; 637 log.maxConcurrentSecureNdpInApp = mMaxSecureNdpInApp; 638 log.maxConcurrentSecureNdpInSystem = mMaxSecureNdpInSystem; 639 log.maxConcurrentNdpPerNdi = mMaxNdpPerNdi; 640 log.histogramRequestNdpStatus = histogramToProtoArray(mInBandNdpStatusData); 641 log.histogramRequestNdpOobStatus = histogramToProtoArray(mOutOfBandNdpStatusData); 642 643 log.histogramNdpCreationTimeMs = histogramToProtoArray( 644 MetricsUtils.logHistogramToGenericBuckets(mNdpCreationTimeDuration, 645 DURATION_LOG_HISTOGRAM)); 646 log.ndpCreationTimeMsMin = mNdpCreationTimeMin; 647 log.ndpCreationTimeMsMax = mNdpCreationTimeMax; 648 log.ndpCreationTimeMsSum = mNdpCreationTimeSum; 649 log.ndpCreationTimeMsSumOfSq = mNdpCreationTimeSumSq; 650 log.ndpCreationTimeMsNumSamples = mNdpCreationTimeNumSamples; 651 652 log.histogramNdpSessionDurationMs = histogramToProtoArray( 653 MetricsUtils.logHistogramToGenericBuckets(mHistogramNdpDuration, 654 DURATION_LOG_HISTOGRAM)); 655 log.histogramNdpRequestType = histogramToNanRequestProtoArray(mHistogramNdpRequestType); 656 } 657 return log; 658 } 659 660 /** 661 * clear Wi-Fi Aware metrics 662 */ clear()663 public void clear() { 664 long now = mClock.getElapsedSinceBootMillis(); 665 synchronized (mLock) { 666 // don't clear mLastEnableUsage since could be valid for next measurement period 667 mHistogramAwareAvailableDurationMs.clear(); 668 mAvailableTimeMs = 0; 669 if (mLastEnableUsageInThisSampleWindowMs != 0) { 670 mLastEnableUsageInThisSampleWindowMs = now; 671 } 672 673 // don't clear mLastEnableAware since could be valid for next measurement period 674 mHistogramAwareEnabledDurationMs.clear(); 675 mEnabledTimeMs = 0; 676 if (mLastEnableAwareInThisSampleWindowMs != 0) { 677 mLastEnableAwareInThisSampleWindowMs = now; 678 } 679 680 mAttachDataByUid.clear(); 681 mAttachStatusData.clear(); 682 mHistogramAttachDuration.clear(); 683 684 mMaxPublishInApp = 0; 685 mMaxSubscribeInApp = 0; 686 mMaxDiscoveryInApp = 0; 687 mMaxPublishInSystem = 0; 688 mMaxSubscribeInSystem = 0; 689 mMaxDiscoveryInSystem = 0; 690 mPublishStatusData.clear(); 691 mSubscribeStatusData.clear(); 692 mHistogramPublishDuration.clear(); 693 mHistogramSubscribeDuration.clear(); 694 mAppsWithDiscoverySessionResourceFailure.clear(); 695 696 mMaxPublishWithRangingInApp = 0; 697 mMaxSubscribeWithRangingInApp = 0; 698 mMaxPublishWithRangingInSystem = 0; 699 mMaxSubscribeWithRangingInSystem = 0; 700 mHistogramSubscribeGeofenceMin.clear(); 701 mHistogramSubscribeGeofenceMax.clear(); 702 mNumSubscribesWithRanging = 0; 703 mNumMatchesWithRanging = 0; 704 mNumMatchesWithoutRangingForRangingEnabledSubscribes = 0; 705 706 mMaxNdiInApp = 0; 707 mMaxNdpInApp = 0; 708 mMaxSecureNdpInApp = 0; 709 mMaxNdiInSystem = 0; 710 mMaxNdpInSystem = 0; 711 mMaxSecureNdpInSystem = 0; 712 mMaxNdpPerNdi = 0; 713 mInBandNdpStatusData.clear(); 714 mOutOfBandNdpStatusData.clear(); 715 716 mNdpCreationTimeDuration.clear(); 717 mNdpCreationTimeMin = -1; 718 mNdpCreationTimeMax = 0; 719 mNdpCreationTimeSum = 0; 720 mNdpCreationTimeSumSq = 0; 721 mNdpCreationTimeNumSamples = 0; 722 723 mHistogramNdpDuration.clear(); 724 mHistogramNdpRequestType.clear(); 725 } 726 } 727 728 /** 729 * Dump all WifiAwareMetrics to console (pw) - this method is never called to dump the 730 * serialized metrics (handled by parent WifiMetrics). 731 * 732 * @param fd unused 733 * @param pw PrintWriter for writing dump to 734 * @param args unused 735 */ dump(FileDescriptor fd, PrintWriter pw, String[] args)736 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 737 synchronized (mLock) { 738 pw.println("mLastEnableUsageMs:" + mLastEnableUsageMs); 739 pw.println( 740 "mLastEnableUsageInThisSampleWindowMs:" + mLastEnableUsageInThisSampleWindowMs); 741 pw.println("mAvailableTimeMs:" + mAvailableTimeMs); 742 pw.println("mHistogramAwareAvailableDurationMs:"); 743 for (int i = 0; i < mHistogramAwareAvailableDurationMs.size(); ++i) { 744 pw.println(" " + mHistogramAwareAvailableDurationMs.keyAt(i) + ": " 745 + mHistogramAwareAvailableDurationMs.valueAt(i)); 746 } 747 748 pw.println("mLastEnableAwareMs:" + mLastEnableAwareMs); 749 pw.println( 750 "mLastEnableAwareInThisSampleWindowMs:" + mLastEnableAwareInThisSampleWindowMs); 751 pw.println("mEnabledTimeMs:" + mEnabledTimeMs); 752 pw.println("mHistogramAwareEnabledDurationMs:"); 753 for (int i = 0; i < mHistogramAwareEnabledDurationMs.size(); ++i) { 754 pw.println(" " + mHistogramAwareEnabledDurationMs.keyAt(i) + ": " 755 + mHistogramAwareEnabledDurationMs.valueAt(i)); 756 } 757 758 pw.println("mAttachDataByUid:"); 759 for (Map.Entry<Integer, AttachData> ade: mAttachDataByUid.entrySet()) { 760 pw.println(" " + "uid=" + ade.getKey() + ": identity=" 761 + ade.getValue().mUsesIdentityCallback + ", maxConcurrent=" 762 + ade.getValue().mMaxConcurrentAttaches); 763 } 764 pw.println("mAttachStatusData:"); 765 for (int i = 0; i < mAttachStatusData.size(); ++i) { 766 pw.println(" " + mAttachStatusData.keyAt(i) + ": " 767 + mAttachStatusData.valueAt(i)); 768 } 769 pw.println("mHistogramAttachDuration:"); 770 for (int i = 0; i < mHistogramAttachDuration.size(); ++i) { 771 pw.println(" " + mHistogramAttachDuration.keyAt(i) + ": " 772 + mHistogramAttachDuration.valueAt(i)); 773 } 774 775 pw.println("mMaxPublishInApp:" + mMaxPublishInApp); 776 pw.println("mMaxSubscribeInApp:" + mMaxSubscribeInApp); 777 pw.println("mMaxDiscoveryInApp:" + mMaxDiscoveryInApp); 778 pw.println("mMaxPublishInSystem:" + mMaxPublishInSystem); 779 pw.println("mMaxSubscribeInSystem:" + mMaxSubscribeInSystem); 780 pw.println("mMaxDiscoveryInSystem:" + mMaxDiscoveryInSystem); 781 pw.println("mPublishStatusData:"); 782 for (int i = 0; i < mPublishStatusData.size(); ++i) { 783 pw.println(" " + mPublishStatusData.keyAt(i) + ": " 784 + mPublishStatusData.valueAt(i)); 785 } 786 pw.println("mSubscribeStatusData:"); 787 for (int i = 0; i < mSubscribeStatusData.size(); ++i) { 788 pw.println(" " + mSubscribeStatusData.keyAt(i) + ": " 789 + mSubscribeStatusData.valueAt(i)); 790 } 791 pw.println("mHistogramPublishDuration:"); 792 for (int i = 0; i < mHistogramPublishDuration.size(); ++i) { 793 pw.println(" " + mHistogramPublishDuration.keyAt(i) + ": " 794 + mHistogramPublishDuration.valueAt(i)); 795 } 796 pw.println("mHistogramSubscribeDuration:"); 797 for (int i = 0; i < mHistogramSubscribeDuration.size(); ++i) { 798 pw.println(" " + mHistogramSubscribeDuration.keyAt(i) + ": " 799 + mHistogramSubscribeDuration.valueAt(i)); 800 } 801 pw.println("mAppsWithDiscoverySessionResourceFailure:"); 802 for (Integer uid: mAppsWithDiscoverySessionResourceFailure) { 803 pw.println(" " + uid); 804 805 } 806 807 pw.println("mMaxPublishWithRangingInApp:" + mMaxPublishWithRangingInApp); 808 pw.println("mMaxSubscribeWithRangingInApp:" + mMaxSubscribeWithRangingInApp); 809 pw.println("mMaxPublishWithRangingInSystem:" + mMaxPublishWithRangingInSystem); 810 pw.println("mMaxSubscribeWithRangingInSystem:" + mMaxSubscribeWithRangingInSystem); 811 pw.println("mHistogramSubscribeGeofenceMin:"); 812 for (int i = 0; i < mHistogramSubscribeGeofenceMin.size(); ++i) { 813 pw.println(" " + mHistogramSubscribeGeofenceMin.keyAt(i) + ": " 814 + mHistogramSubscribeGeofenceMin.valueAt(i)); 815 } 816 pw.println("mHistogramSubscribeGeofenceMax:"); 817 for (int i = 0; i < mHistogramSubscribeGeofenceMax.size(); ++i) { 818 pw.println(" " + mHistogramSubscribeGeofenceMax.keyAt(i) + ": " 819 + mHistogramSubscribeGeofenceMax.valueAt(i)); 820 } 821 pw.println("mNumSubscribesWithRanging:" + mNumSubscribesWithRanging); 822 pw.println("mNumMatchesWithRanging:" + mNumMatchesWithRanging); 823 pw.println("mNumMatchesWithoutRangingForRangingEnabledSubscribes:" 824 + mNumMatchesWithoutRangingForRangingEnabledSubscribes); 825 826 pw.println("mMaxNdiInApp:" + mMaxNdiInApp); 827 pw.println("mMaxNdpInApp:" + mMaxNdpInApp); 828 pw.println("mMaxSecureNdpInApp:" + mMaxSecureNdpInApp); 829 pw.println("mMaxNdiInSystem:" + mMaxNdiInSystem); 830 pw.println("mMaxNdpInSystem:" + mMaxNdpInSystem); 831 pw.println("mMaxSecureNdpInSystem:" + mMaxSecureNdpInSystem); 832 pw.println("mMaxNdpPerNdi:" + mMaxNdpPerNdi); 833 pw.println("mInBandNdpStatusData:"); 834 for (int i = 0; i < mInBandNdpStatusData.size(); ++i) { 835 pw.println(" " + mInBandNdpStatusData.keyAt(i) + ": " 836 + mInBandNdpStatusData.valueAt(i)); 837 } 838 pw.println("mOutOfBandNdpStatusData:"); 839 for (int i = 0; i < mOutOfBandNdpStatusData.size(); ++i) { 840 pw.println(" " + mOutOfBandNdpStatusData.keyAt(i) + ": " 841 + mOutOfBandNdpStatusData.valueAt(i)); 842 } 843 844 pw.println("mNdpCreationTimeDuration:"); 845 for (int i = 0; i < mNdpCreationTimeDuration.size(); ++i) { 846 pw.println(" " + mNdpCreationTimeDuration.keyAt(i) + ": " 847 + mNdpCreationTimeDuration.valueAt(i)); 848 } 849 pw.println("mNdpCreationTimeMin:" + mNdpCreationTimeMin); 850 pw.println("mNdpCreationTimeMax:" + mNdpCreationTimeMax); 851 pw.println("mNdpCreationTimeSum:" + mNdpCreationTimeSum); 852 pw.println("mNdpCreationTimeSumSq:" + mNdpCreationTimeSumSq); 853 pw.println("mNdpCreationTimeNumSamples:" + mNdpCreationTimeNumSamples); 854 855 pw.println("mHistogramNdpDuration:"); 856 for (int i = 0; i < mHistogramNdpDuration.size(); ++i) { 857 pw.println(" " + mHistogramNdpDuration.keyAt(i) + ": " 858 + mHistogramNdpDuration.valueAt(i)); 859 } 860 pw.println("mNdpRequestType:"); 861 for (int i = 0; i < mHistogramNdpRequestType.size(); ++i) { 862 pw.println(" " + mHistogramNdpRequestType.keyAt(i) + ": " 863 + mHistogramNdpRequestType.valueAt(i)); 864 } 865 } 866 } 867 868 // histogram utilities 869 /** 870 * Convert a generic bucket to Aware HistogramBucket proto. 871 */ 872 @VisibleForTesting histogramToProtoArray( MetricsUtils.GenericBucket[] buckets)873 public static WifiMetricsProto.WifiAwareLog.HistogramBucket[] histogramToProtoArray( 874 MetricsUtils.GenericBucket[] buckets) { 875 WifiMetricsProto.WifiAwareLog.HistogramBucket[] protoArray = 876 new WifiMetricsProto.WifiAwareLog.HistogramBucket[buckets.length]; 877 878 for (int i = 0; i < buckets.length; ++i) { 879 protoArray[i] = new WifiMetricsProto.WifiAwareLog.HistogramBucket(); 880 protoArray[i].start = buckets[i].start; 881 protoArray[i].end = buckets[i].end; 882 protoArray[i].count = buckets[i].count; 883 } 884 885 return protoArray; 886 } 887 888 /** 889 * Adds the NanStatusType to the histogram (translating to the proto enumeration of the status). 890 */ addNanHalStatusToHistogram(int halStatus, SparseIntArray histogram)891 public static void addNanHalStatusToHistogram(int halStatus, SparseIntArray histogram) { 892 int protoStatus = convertNanStatusCodeToProtoEnum(halStatus); 893 int newValue = histogram.get(protoStatus) + 1; 894 histogram.put(protoStatus, newValue); 895 } 896 897 /** 898 * Converts a histogram of proto NanStatusTypeEnum to a raw proto histogram. 899 */ 900 @VisibleForTesting histogramToProtoArray( SparseIntArray histogram)901 public static WifiMetricsProto.WifiAwareLog.NanStatusHistogramBucket[] histogramToProtoArray( 902 SparseIntArray histogram) { 903 WifiMetricsProto.WifiAwareLog.NanStatusHistogramBucket[] protoArray = 904 new WifiMetricsProto.WifiAwareLog.NanStatusHistogramBucket[histogram.size()]; 905 906 for (int i = 0; i < histogram.size(); ++i) { 907 protoArray[i] = new WifiMetricsProto.WifiAwareLog.NanStatusHistogramBucket(); 908 protoArray[i].nanStatusType = histogram.keyAt(i); 909 protoArray[i].count = histogram.valueAt(i); 910 } 911 912 return protoArray; 913 } 914 915 /** 916 * Convert a NanStatusCode to a Metrics proto enum NanStatusCodeEnum. 917 */ convertNanStatusCodeToProtoEnum(int nanStatusCode)918 public static int convertNanStatusCodeToProtoEnum(int nanStatusCode) { 919 switch (nanStatusCode) { 920 case NanStatusCode.SUCCESS: 921 return WifiMetricsProto.WifiAwareLog.SUCCESS; 922 case NanStatusCode.INTERNAL_FAILURE: 923 return WifiMetricsProto.WifiAwareLog.INTERNAL_FAILURE; 924 case NanStatusCode.PROTOCOL_FAILURE: 925 return WifiMetricsProto.WifiAwareLog.PROTOCOL_FAILURE; 926 case NanStatusCode.INVALID_SESSION_ID: 927 return WifiMetricsProto.WifiAwareLog.INVALID_SESSION_ID; 928 case NanStatusCode.NO_RESOURCES_AVAILABLE: 929 return WifiMetricsProto.WifiAwareLog.NO_RESOURCES_AVAILABLE; 930 case NanStatusCode.INVALID_ARGS: 931 return WifiMetricsProto.WifiAwareLog.INVALID_ARGS; 932 case NanStatusCode.INVALID_PEER_ID: 933 return WifiMetricsProto.WifiAwareLog.INVALID_PEER_ID; 934 case NanStatusCode.INVALID_NDP_ID: 935 return WifiMetricsProto.WifiAwareLog.INVALID_NDP_ID; 936 case NanStatusCode.NAN_NOT_ALLOWED: 937 return WifiMetricsProto.WifiAwareLog.NAN_NOT_ALLOWED; 938 case NanStatusCode.NO_OTA_ACK: 939 return WifiMetricsProto.WifiAwareLog.NO_OTA_ACK; 940 case NanStatusCode.ALREADY_ENABLED: 941 return WifiMetricsProto.WifiAwareLog.ALREADY_ENABLED; 942 case NanStatusCode.FOLLOWUP_TX_QUEUE_FULL: 943 return WifiMetricsProto.WifiAwareLog.FOLLOWUP_TX_QUEUE_FULL; 944 case NanStatusCode.UNSUPPORTED_CONCURRENCY_NAN_DISABLED: 945 return WifiMetricsProto.WifiAwareLog.UNSUPPORTED_CONCURRENCY_NAN_DISABLED; 946 default: 947 Log.e(TAG, "Unrecognized NanStatusCode: " + nanStatusCode); 948 return WifiMetricsProto.WifiAwareLog.UNKNOWN_HAL_STATUS; 949 } 950 } 951 952 /** 953 * Convert a NanStatusCode to a WifiStatsLog enum AwareStatus. 954 */ convertNanStatusCodeToWifiStatsLogEnum(int nanStatusCode)955 public static int convertNanStatusCodeToWifiStatsLogEnum(int nanStatusCode) { 956 switch (nanStatusCode) { 957 case NanStatusCode.SUCCESS: 958 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__STATUS__ST_SUCCESS; 959 case NanStatusCode.INTERNAL_FAILURE: 960 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__STATUS__ST_INTERNAL_FAILURE; 961 case NanStatusCode.PROTOCOL_FAILURE: 962 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__STATUS__ST_PROTOCOL_FAILURE; 963 case NanStatusCode.INVALID_SESSION_ID: 964 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__STATUS__ST_INVALID_SESSION_ID; 965 case NanStatusCode.NO_RESOURCES_AVAILABLE: 966 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__STATUS__ST_NO_RESOURCES_AVAILABLE; 967 case NanStatusCode.INVALID_ARGS: 968 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__STATUS__ST_INVALID_ARGS; 969 case NanStatusCode.INVALID_PEER_ID: 970 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__STATUS__ST_INVALID_PEER_ID; 971 case NanStatusCode.INVALID_NDP_ID: 972 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__STATUS__ST_INVALID_NDP_ID; 973 case NanStatusCode.NAN_NOT_ALLOWED: 974 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__STATUS__ST_NAN_NOT_ALLOWED; 975 case NanStatusCode.NO_OTA_ACK: 976 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__STATUS__ST_NO_OTA_ACK; 977 case NanStatusCode.ALREADY_ENABLED: 978 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__STATUS__ST_ALREADY_ENABLED; 979 case NanStatusCode.FOLLOWUP_TX_QUEUE_FULL: 980 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__STATUS__ST_FOLLOWUP_TX_QUEUE_FULL; 981 case NanStatusCode.UNSUPPORTED_CONCURRENCY_NAN_DISABLED: 982 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__STATUS__ST_UNSUPPORTED_CONCURRENCY; 983 default: 984 Log.d(TAG, "Unrecognized NanStatusCode: " + nanStatusCode); 985 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__STATUS__ST_GENERIC_FAILURE; 986 } 987 } 988 989 /** 990 * Convert a NanStatusCode to a WifiStatsLog enum AwareStatus. 991 */ convertNdpRoleToWifiStatsLogEnum(int role)992 public static int convertNdpRoleToWifiStatsLogEnum(int role) { 993 switch (role) { 994 case WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR: 995 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__ROLE__ROLE_INITIATOR; 996 case WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER: 997 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__ROLE__ROLE_RESPONDER; 998 default: 999 Log.e(TAG, "Unrecognized role: " + role); 1000 return WifiStatsLog.WIFI_AWARE_NDP_REPORTED__ROLE__ROLE_UNKNOWN; 1001 } 1002 } 1003 1004 /** 1005 * Record NDP request type 1006 */ recordNdpRequestType(int type)1007 public void recordNdpRequestType(int type) { 1008 int protoType = convertNdpRequestTypeToProtoEnum(type); 1009 mHistogramNdpRequestType.put(protoType, mHistogramNdpRequestType.get(protoType) + 1); 1010 } 1011 convertNdpRequestTypeToProtoEnum(int ndpRequestType)1012 private int convertNdpRequestTypeToProtoEnum(int ndpRequestType) { 1013 switch (ndpRequestType) { 1014 case NETWORK_SPECIFIER_TYPE_IB: 1015 return WifiMetricsProto.WifiAwareLog.NETWORK_SPECIFIER_TYPE_IB; 1016 case NETWORK_SPECIFIER_TYPE_IB_ANY_PEER: 1017 return WifiMetricsProto.WifiAwareLog.NETWORK_SPECIFIER_TYPE_IB_ANY_PEER; 1018 case NETWORK_SPECIFIER_TYPE_OOB: 1019 return WifiMetricsProto.WifiAwareLog.NETWORK_SPECIFIER_TYPE_OOB; 1020 case NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER: 1021 return WifiMetricsProto.WifiAwareLog.NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER; 1022 default: 1023 Log.e(TAG, "Unrecognized NdpRequestType: " + ndpRequestType); 1024 return WifiMetricsProto.WifiAwareLog.NETWORK_SPECIFIER_TYPE_UNKNOWN; 1025 } 1026 } 1027 1028 1029 /** 1030 * Converts a histogram of proto NdpRequestTypeEnum to a raw proto histogram. 1031 */ 1032 @VisibleForTesting 1033 public static WifiMetricsProto.WifiAwareLog.NdpRequestTypeHistogramBucket[] histogramToNanRequestProtoArray(SparseIntArray histogram)1034 histogramToNanRequestProtoArray(SparseIntArray histogram) { 1035 WifiMetricsProto.WifiAwareLog.NdpRequestTypeHistogramBucket[] protoArray = 1036 new WifiMetricsProto.WifiAwareLog.NdpRequestTypeHistogramBucket[histogram.size()]; 1037 1038 for (int i = 0; i < histogram.size(); ++i) { 1039 protoArray[i] = new WifiMetricsProto.WifiAwareLog.NdpRequestTypeHistogramBucket(); 1040 protoArray[i].ndpRequestType = histogram.keyAt(i); 1041 protoArray[i].count = histogram.valueAt(i); 1042 } 1043 1044 return protoArray; 1045 } 1046 } 1047