diff options
author | Oscar Shu <xshu@google.com> | 2018-10-02 18:11:48 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-10-02 18:11:48 +0000 |
commit | 91c4e97cd423872b3b9e0358efb9081ee7344890 (patch) | |
tree | eaa11d44bc7943248a2ca4bc7455041cd235215c | |
parent | 666a511081fd80908ab7ce437d35a48a07791df5 (diff) | |
parent | f5e766890949a9abc6079678b0d36b52d4b5c483 (diff) |
Merge "Metrics for wifi link layer stats usage"
4 files changed, 145 insertions, 1 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index 7781805b2..3bae1ba26 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -4897,6 +4897,7 @@ public class ClientModeImpl extends StateMachine { if (message.arg1 == mRssiPollToken) { WifiLinkLayerStats stats = getWifiLinkLayerStats(); mWifiDataStall.checkForDataStall(mLastLinkLayerStats, stats); + mWifiMetrics.incrementWifiLinkLayerUsageStats(stats); mLastLinkLayerStats = stats; // Get Info and continue polling diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java index 1bcd22d0c..5f1e09b75 100644 --- a/service/java/com/android/server/wifi/WifiMetrics.java +++ b/service/java/com/android/server/wifi/WifiMetrics.java @@ -30,7 +30,6 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.SystemProperties; - import android.provider.Settings; import android.util.Base64; import android.util.Log; @@ -55,6 +54,7 @@ import com.android.server.wifi.nano.WifiMetricsProto.SoftApConnectedClientsEvent import com.android.server.wifi.nano.WifiMetricsProto.StaEvent; import com.android.server.wifi.nano.WifiMetricsProto.StaEvent.ConfigInfo; import com.android.server.wifi.nano.WifiMetricsProto.WifiIsUnusableEvent; +import com.android.server.wifi.nano.WifiMetricsProto.WifiLinkLayerUsageStats; import com.android.server.wifi.nano.WifiMetricsProto.WpsMetrics; import com.android.server.wifi.rtt.RttMetrics; import com.android.server.wifi.util.InformationElementUtil; @@ -130,6 +130,7 @@ public class WifiMetrics { private WifiAwareMetrics mWifiAwareMetrics; private RttMetrics mRttMetrics; private final PnoScanMetrics mPnoScanMetrics = new PnoScanMetrics(); + private final WifiLinkLayerUsageStats mWifiLinkLayerUsageStats = new WifiLinkLayerUsageStats(); private final WpsMetrics mWpsMetrics = new WpsMetrics(); private final ExperimentValues mExperimentValues = new ExperimentValues(); private Handler mHandler; @@ -140,6 +141,7 @@ public class WifiMetrics { private Context mContext; private FrameworkFacade mFacade; private WifiDataStall mWifiDataStall; + private WifiLinkLayerStats mLastLinkLayerStats; /** Tracks if we should be logging WifiIsUnusableEvent */ private boolean mUnusableEventLogging = false; @@ -541,6 +543,45 @@ public class WifiMetrics { } /** + * Increment cumulative counters for link layer stats. + * @param newStats + */ + public void incrementWifiLinkLayerUsageStats(WifiLinkLayerStats newStats) { + if (newStats == null) { + return; + } + if (mLastLinkLayerStats == null) { + mLastLinkLayerStats = newStats; + return; + } + if (!newLinkLayerStatsIsValid(mLastLinkLayerStats, newStats)) { + // This could mean the radio chip is reset or the data is incorrectly reported. + // Don't increment any counts and discard the possibly corrupt |newStats| completely. + mLastLinkLayerStats = null; + return; + } + mWifiLinkLayerUsageStats.loggingDurationMs += + (newStats.timeStampInMs - mLastLinkLayerStats.timeStampInMs); + mWifiLinkLayerUsageStats.radioOnTimeMs += (newStats.on_time - mLastLinkLayerStats.on_time); + mWifiLinkLayerUsageStats.radioTxTimeMs += (newStats.tx_time - mLastLinkLayerStats.tx_time); + mWifiLinkLayerUsageStats.radioRxTimeMs += (newStats.rx_time - mLastLinkLayerStats.rx_time); + mWifiLinkLayerUsageStats.radioScanTimeMs += + (newStats.on_time_scan - mLastLinkLayerStats.on_time_scan); + mLastLinkLayerStats = newStats; + } + + private boolean newLinkLayerStatsIsValid(WifiLinkLayerStats oldStats, + WifiLinkLayerStats newStats) { + if (newStats.on_time < oldStats.on_time + || newStats.tx_time < oldStats.tx_time + || newStats.rx_time < oldStats.rx_time + || newStats.on_time_scan < oldStats.on_time_scan) { + return false; + } + return true; + } + + /** * Increment total number of attempts to start a pno scan */ public void incrementPnoScanStartAttempCount() { @@ -2222,6 +2263,17 @@ public class WifiMetrics { pw.println("mPnoScanMetrics.numPnoFoundNetworkEvents=" + mPnoScanMetrics.numPnoFoundNetworkEvents); + pw.println("mWifiLinkLayerUsageStats.loggingDurationMs=" + + mWifiLinkLayerUsageStats.loggingDurationMs); + pw.println("mWifiLinkLayerUsageStats.radioOnTimeMs=" + + mWifiLinkLayerUsageStats.radioOnTimeMs); + pw.println("mWifiLinkLayerUsageStats.radioTxTimeMs=" + + mWifiLinkLayerUsageStats.radioTxTimeMs); + pw.println("mWifiLinkLayerUsageStats.radioRxTimeMs=" + + mWifiLinkLayerUsageStats.radioRxTimeMs); + pw.println("mWifiLinkLayerUsageStats.radioScanTimeMs=" + + mWifiLinkLayerUsageStats.radioScanTimeMs); + pw.println("mWifiLogProto.connectToNetworkNotificationCount=" + mConnectToNetworkNotificationCount.toString()); pw.println("mWifiLogProto.connectToNetworkNotificationActionCount=" @@ -2569,6 +2621,7 @@ public class WifiMetrics { mWifiLogProto.wifiRttLog = mRttMetrics.consolidateProto(); mWifiLogProto.pnoScanMetrics = mPnoScanMetrics; + mWifiLogProto.wifiLinkLayerUsageStats = mWifiLinkLayerUsageStats; /** * Convert the SparseIntArray of "Connect to Network" notification types and counts to @@ -2742,6 +2795,7 @@ public class WifiMetrics { mAvailableSavedPasspointProviderProfilesInScanHistogram.clear(); mAvailableSavedPasspointProviderBssidsInScanHistogram.clear(); mPnoScanMetrics.clear(); + mWifiLinkLayerUsageStats.clear(); mConnectToNetworkNotificationCount.clear(); mConnectToNetworkNotificationActionCount.clear(); mNumOpenNetworkRecommendationUpdates = 0; diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java index 1dade80db..e7a80bfc0 100644 --- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java @@ -2696,6 +2696,7 @@ public class ClientModeImplTest { /** * Verify that we check for data stall during rssi poll + * and then check that wifi link layer usage data are being updated. */ @Test public void verifyRssiPollChecksDataStall() throws Exception { @@ -2711,5 +2712,6 @@ public class ClientModeImplTest { mCmi.sendMessage(ClientModeImpl.CMD_RSSI_POLL, 1); mLooper.dispatchAll(); verify(mWifiDataStall).checkForDataStall(oldLLStats, newLLStats); + verify(mWifiMetrics).incrementWifiLinkLayerUsageStats(newLLStats); } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java index f566d0286..ba74089a9 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java @@ -72,6 +72,7 @@ import java.util.BitSet; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -84,6 +85,7 @@ public class WifiMetricsTest { WifiMetrics mWifiMetrics; WifiMetricsProto.WifiLog mDecodedProto; TestLooper mTestLooper; + Random mRandom = new Random(); @Mock Context mContext; @Mock FrameworkFacade mFacade; @Mock Clock mClock; @@ -2288,4 +2290,89 @@ public class WifiMetricsTest { assertEquals("LinkSpeedCounts should not be logged for out of bound values", 0, mDecodedProto.linkSpeedCounts.length); } + + private int nextRandInt() { + return mRandom.nextInt(10000); + } + + private WifiLinkLayerStats nextRandomStats(WifiLinkLayerStats current) { + WifiLinkLayerStats out = new WifiLinkLayerStats(); + out.timeStampInMs = current.timeStampInMs + nextRandInt(); + out.on_time = current.on_time + nextRandInt(); + out.tx_time = current.tx_time + nextRandInt(); + out.rx_time = current.rx_time + nextRandInt(); + out.on_time_scan = current.on_time_scan + nextRandInt(); + return out; + } + + private void assertWifiLinkLayerUsageHasDiff(WifiLinkLayerStats oldStats, + WifiLinkLayerStats newStats) { + assertEquals(newStats.timeStampInMs - oldStats.timeStampInMs, + mDecodedProto.wifiLinkLayerUsageStats.loggingDurationMs); + assertEquals(newStats.on_time - oldStats.on_time, + mDecodedProto.wifiLinkLayerUsageStats.radioOnTimeMs); + assertEquals(newStats.tx_time - oldStats.tx_time, + mDecodedProto.wifiLinkLayerUsageStats.radioTxTimeMs); + assertEquals(newStats.rx_time - oldStats.rx_time, + mDecodedProto.wifiLinkLayerUsageStats.radioRxTimeMs); + assertEquals(newStats.on_time_scan - oldStats.on_time_scan, + mDecodedProto.wifiLinkLayerUsageStats.radioScanTimeMs); + } + + /** + * Verify that WifiMetrics is counting link layer usage correctly when given a series of + * valid input. + * @throws Exception + */ + @Test + public void testWifiLinkLayerUsageStats() throws Exception { + WifiLinkLayerStats stat1 = nextRandomStats(new WifiLinkLayerStats()); + WifiLinkLayerStats stat2 = nextRandomStats(stat1); + WifiLinkLayerStats stat3 = nextRandomStats(stat2); + mWifiMetrics.incrementWifiLinkLayerUsageStats(stat1); + mWifiMetrics.incrementWifiLinkLayerUsageStats(stat2); + mWifiMetrics.incrementWifiLinkLayerUsageStats(stat3); + dumpProtoAndDeserialize(); + + // After 2 increments, the counters should have difference between |stat1| and |stat3| + assertWifiLinkLayerUsageHasDiff(stat1, stat3); + } + + /** + * Verify that null input is handled and wifi link layer usage stats are not incremented. + * @throws Exception + */ + @Test + public void testWifiLinkLayerUsageStatsNullInput() throws Exception { + WifiLinkLayerStats stat1 = nextRandomStats(new WifiLinkLayerStats()); + WifiLinkLayerStats stat2 = null; + mWifiMetrics.incrementWifiLinkLayerUsageStats(stat1); + mWifiMetrics.incrementWifiLinkLayerUsageStats(stat2); + dumpProtoAndDeserialize(); + + // Counter should be zero + assertWifiLinkLayerUsageHasDiff(stat1, stat1); + } + + /** + * Verify that when the new data appears to be bad link layer usage stats are not being + * incremented and the buffered WifiLinkLayerStats get cleared. + * @throws Exception + */ + @Test + public void testWifiLinkLayerUsageStatsChipReset() throws Exception { + WifiLinkLayerStats stat1 = nextRandomStats(new WifiLinkLayerStats()); + WifiLinkLayerStats stat2 = nextRandomStats(stat1); + stat2.on_time = stat1.on_time - 1; + WifiLinkLayerStats stat3 = nextRandomStats(stat2); + WifiLinkLayerStats stat4 = nextRandomStats(stat3); + mWifiMetrics.incrementWifiLinkLayerUsageStats(stat1); + mWifiMetrics.incrementWifiLinkLayerUsageStats(stat2); + mWifiMetrics.incrementWifiLinkLayerUsageStats(stat3); + mWifiMetrics.incrementWifiLinkLayerUsageStats(stat4); + dumpProtoAndDeserialize(); + + // Should only count the difference between |stat3| and |stat4| + assertWifiLinkLayerUsageHasDiff(stat3, stat4); + } } |