• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.server.wifi;
17 
18 import static android.content.Intent.ACTION_SCREEN_OFF;
19 import static android.content.Intent.ACTION_SCREEN_ON;
20 import static android.net.wifi.WifiManager.DEVICE_MOBILITY_STATE_HIGH_MVMT;
21 import static android.net.wifi.WifiManager.DEVICE_MOBILITY_STATE_LOW_MVMT;
22 import static android.net.wifi.WifiManager.DEVICE_MOBILITY_STATE_STATIONARY;
23 import static android.net.wifi.WifiManager.DEVICE_MOBILITY_STATE_UNKNOWN;
24 
25 import static com.android.server.wifi.WifiMetricsTestUtil.assertDeviceMobilityStatePnoScanStatsEqual;
26 import static com.android.server.wifi.WifiMetricsTestUtil.assertExperimentProbeCountsEqual;
27 import static com.android.server.wifi.WifiMetricsTestUtil.assertHistogramBucketsEqual;
28 import static com.android.server.wifi.WifiMetricsTestUtil.assertKeyCountsEqual;
29 import static com.android.server.wifi.WifiMetricsTestUtil.assertLinkProbeFailureReasonCountsEqual;
30 import static com.android.server.wifi.WifiMetricsTestUtil.assertLinkProbeStaEventsEqual;
31 import static com.android.server.wifi.WifiMetricsTestUtil.buildDeviceMobilityStatePnoScanStats;
32 import static com.android.server.wifi.WifiMetricsTestUtil.buildExperimentProbeCounts;
33 import static com.android.server.wifi.WifiMetricsTestUtil.buildHistogramBucketInt32;
34 import static com.android.server.wifi.WifiMetricsTestUtil.buildInt32Count;
35 import static com.android.server.wifi.WifiMetricsTestUtil.buildLinkProbeFailureReasonCount;
36 import static com.android.server.wifi.WifiMetricsTestUtil.buildLinkProbeFailureStaEvent;
37 import static com.android.server.wifi.WifiMetricsTestUtil.buildLinkProbeSuccessStaEvent;
38 import static com.android.server.wifi.proto.nano.WifiMetricsProto.StaEvent.TYPE_LINK_PROBE;
39 
40 import static org.junit.Assert.assertEquals;
41 import static org.junit.Assert.assertFalse;
42 import static org.junit.Assert.assertNotNull;
43 import static org.junit.Assert.assertNull;
44 import static org.junit.Assert.assertTrue;
45 import static org.junit.Assert.fail;
46 import static org.mockito.Mockito.any;
47 import static org.mockito.Mockito.anyBoolean;
48 import static org.mockito.Mockito.anyInt;
49 import static org.mockito.Mockito.anyString;
50 import static org.mockito.Mockito.atLeastOnce;
51 import static org.mockito.Mockito.doThrow;
52 import static org.mockito.Mockito.eq;
53 import static org.mockito.Mockito.mock;
54 import static org.mockito.Mockito.never;
55 import static org.mockito.Mockito.times;
56 import static org.mockito.Mockito.verify;
57 import static org.mockito.Mockito.when;
58 
59 import static java.lang.StrictMath.toIntExact;
60 
61 import android.app.ActivityManager;
62 import android.content.BroadcastReceiver;
63 import android.content.Context;
64 import android.content.Intent;
65 import android.net.wifi.EAPConstants;
66 import android.net.wifi.IOnWifiUsabilityStatsListener;
67 import android.net.wifi.ScanResult;
68 import android.net.wifi.SoftApCapability;
69 import android.net.wifi.SoftApConfiguration;
70 import android.net.wifi.SoftApInfo;
71 import android.net.wifi.SupplicantState;
72 import android.net.wifi.WifiConfiguration;
73 import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
74 import android.net.wifi.WifiEnterpriseConfig;
75 import android.net.wifi.WifiInfo;
76 import android.net.wifi.WifiManager;
77 import android.net.wifi.WifiSsid;
78 import android.net.wifi.hotspot2.PasspointConfiguration;
79 import android.net.wifi.hotspot2.ProvisioningCallback;
80 import android.net.wifi.hotspot2.pps.Credential;
81 import android.net.wifi.nl80211.WifiNl80211Manager;
82 import android.os.Handler;
83 import android.os.IBinder;
84 import android.os.Message;
85 import android.os.PowerManager;
86 import android.os.RemoteException;
87 import android.os.test.TestLooper;
88 import android.telephony.TelephonyManager;
89 import android.util.Base64;
90 import android.util.Pair;
91 import android.util.SparseIntArray;
92 
93 import androidx.test.filters.MediumTest;
94 import androidx.test.filters.SmallTest;
95 
96 import com.android.dx.mockito.inline.extended.ExtendedMockito;
97 import com.android.server.wifi.WifiLinkLayerStats.PeerInfo;
98 import com.android.server.wifi.WifiLinkLayerStats.RadioStat;
99 import com.android.server.wifi.WifiLinkLayerStats.RateStat;
100 import com.android.server.wifi.aware.WifiAwareMetrics;
101 import com.android.server.wifi.hotspot2.NetworkDetail;
102 import com.android.server.wifi.hotspot2.PasspointManager;
103 import com.android.server.wifi.hotspot2.PasspointMatch;
104 import com.android.server.wifi.hotspot2.PasspointProvider;
105 import com.android.server.wifi.p2p.WifiP2pMetrics;
106 import com.android.server.wifi.proto.WifiStatsLog;
107 import com.android.server.wifi.proto.nano.WifiMetricsProto;
108 import com.android.server.wifi.proto.nano.WifiMetricsProto.ConnectToNetworkNotificationAndActionCount;
109 import com.android.server.wifi.proto.nano.WifiMetricsProto.DeviceMobilityStatePnoScanStats;
110 import com.android.server.wifi.proto.nano.WifiMetricsProto.HealthMonitorFailureStats;
111 import com.android.server.wifi.proto.nano.WifiMetricsProto.HealthMonitorMetrics;
112 import com.android.server.wifi.proto.nano.WifiMetricsProto.HistogramBucketInt32;
113 import com.android.server.wifi.proto.nano.WifiMetricsProto.Int32Count;
114 import com.android.server.wifi.proto.nano.WifiMetricsProto.LinkProbeStats;
115 import com.android.server.wifi.proto.nano.WifiMetricsProto.LinkProbeStats.ExperimentProbeCounts;
116 import com.android.server.wifi.proto.nano.WifiMetricsProto.LinkProbeStats.LinkProbeFailureReasonCount;
117 import com.android.server.wifi.proto.nano.WifiMetricsProto.NetworkDisableReason;
118 import com.android.server.wifi.proto.nano.WifiMetricsProto.NetworkSelectionExperimentDecisions;
119 import com.android.server.wifi.proto.nano.WifiMetricsProto.PasspointProfileTypeCount;
120 import com.android.server.wifi.proto.nano.WifiMetricsProto.PasspointProvisionStats;
121 import com.android.server.wifi.proto.nano.WifiMetricsProto.PnoScanMetrics;
122 import com.android.server.wifi.proto.nano.WifiMetricsProto.RadioStats;
123 import com.android.server.wifi.proto.nano.WifiMetricsProto.RateStats;
124 import com.android.server.wifi.proto.nano.WifiMetricsProto.SoftApConnectedClientsEvent;
125 import com.android.server.wifi.proto.nano.WifiMetricsProto.StaEvent;
126 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiIsUnusableEvent;
127 import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiRadioUsage;
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.util.InformationElementUtil;
132 import com.android.wifi.resources.R;
133 
134 import org.junit.After;
135 import org.junit.Before;
136 import org.junit.Test;
137 import org.mockito.ArgumentCaptor;
138 import org.mockito.Captor;
139 import org.mockito.Mock;
140 import org.mockito.MockitoAnnotations;
141 import org.mockito.MockitoSession;
142 import org.mockito.quality.Strictness;
143 
144 import java.io.ByteArrayOutputStream;
145 import java.io.FileDescriptor;
146 import java.io.PrintWriter;
147 import java.io.StringWriter;
148 import java.time.Duration;
149 import java.util.ArrayList;
150 import java.util.Arrays;
151 import java.util.BitSet;
152 import java.util.HashMap;
153 import java.util.HashSet;
154 import java.util.List;
155 import java.util.Map;
156 import java.util.Random;
157 import java.util.Set;
158 import java.util.regex.Matcher;
159 import java.util.regex.Pattern;
160 
161 /**
162  * Unit tests for {@link com.android.server.wifi.WifiMetrics}.
163  */
164 @SmallTest
165 public class WifiMetricsTest extends WifiBaseTest {
166 
167     WifiMetrics mWifiMetrics;
168     WifiMetricsProto.WifiLog mDecodedProto;
169     TestLooper mTestLooper;
170     Random mRandom = new Random();
171     private static final int TEST_NETWORK_ID = 42;
172     public static final String TEST_IFACE_NAME = "wlan0";
173     public static final String TEST_IFACE_NAME2 = "wlan1";
174     private MockitoSession mSession;
175     @Mock Context mContext;
176     MockResources mResources;
177     @Mock FrameworkFacade mFacade;
178     @Mock Clock mClock;
179     @Mock ScoringParams mScoringParams;
180     @Mock WifiConfigManager mWcm;
181     @Mock WifiBlocklistMonitor mWifiBlocklistMonitor;
182     @Mock PasspointManager mPpm;
183     @Mock WifiNetworkSelector mWns;
184     @Mock WifiPowerMetrics mWifiPowerMetrics;
185     @Mock WifiDataStall mWifiDataStall;
186     @Mock WifiChannelUtilization mWifiChannelUtilization;
187     @Mock WifiSettingsStore mWifiSettingsStore;
188     @Mock WifiHealthMonitor mWifiHealthMonitor;
189     @Mock IBinder mAppBinder;
190     @Mock IOnWifiUsabilityStatsListener mOnWifiUsabilityStatsListener;
191     @Mock WifiP2pMetrics mWifiP2pMetrics;
192     @Mock DppMetrics mDppMetrics;
193     @Mock WifiScoreCard mWifiScoreCard;
194     @Mock WifiScoreCard.PerNetwork mPerNetwork;
195     @Mock WifiScoreCard.NetworkConnectionStats mNetworkConnectionStats;
196     @Mock PowerManager mPowerManager;
197     @Mock WifiMonitor mWifiMonitor;
198     @Mock ActiveModeWarden mActiveModeWarden;
199 
200     @Captor ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
201     @Captor ArgumentCaptor<ActiveModeWarden.ModeChangeCallback> mModeChangeCallbackArgumentCaptor;
202     @Captor ArgumentCaptor<Handler> mHandlerCaptor;
203 
204     @Before
setUp()205     public void setUp() throws Exception {
206         MockitoAnnotations.initMocks(this);
207         mDecodedProto = null;
208         when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 0);
209         mTestLooper = new TestLooper();
210         mResources = new MockResources();
211         when(mContext.getResources()).thenReturn(mResources);
212         when(mContext.getSystemService(PowerManager.class)).thenReturn(mPowerManager);
213         when(mPowerManager.isInteractive()).thenReturn(true);
214         mWifiMetrics = new WifiMetrics(mContext, mFacade, mClock, mTestLooper.getLooper(),
215                 new WifiAwareMetrics(mClock), new RttMetrics(mClock), mWifiPowerMetrics,
216                 mWifiP2pMetrics, mDppMetrics, mWifiMonitor);
217         mWifiMetrics.setWifiConfigManager(mWcm);
218         mWifiMetrics.setWifiBlocklistMonitor(mWifiBlocklistMonitor);
219         mWifiMetrics.setPasspointManager(mPpm);
220         mWifiMetrics.setScoringParams(mScoringParams);
221         mWifiMetrics.setWifiNetworkSelector(mWns);
222         mWifiMetrics.setWifiDataStall(mWifiDataStall);
223         mWifiMetrics.setWifiChannelUtilization(mWifiChannelUtilization);
224         mWifiMetrics.setWifiSettingsStore(mWifiSettingsStore);
225         mWifiMetrics.setWifiHealthMonitor(mWifiHealthMonitor);
226         mWifiMetrics.setWifiScoreCard(mWifiScoreCard);
227         when(mOnWifiUsabilityStatsListener.asBinder()).thenReturn(mAppBinder);
228         when(mWifiScoreCard.lookupNetwork(anyString())).thenReturn(mPerNetwork);
229         when(mPerNetwork.getRecentStats()).thenReturn(mNetworkConnectionStats);
230         verify(mContext, atLeastOnce()).registerReceiver(
231                 mBroadcastReceiverCaptor.capture(), any(), any(), any());
232 
233         mWifiMetrics.registerForWifiMonitorEvents("wlan0");
234         verify(mWifiMonitor, atLeastOnce())
235                 .registerHandler(eq("wlan0"), anyInt(), mHandlerCaptor.capture());
236 
237         mWifiMetrics.setActiveModeWarden(mActiveModeWarden);
238         verify(mActiveModeWarden).registerModeChangeCallback(
239                 mModeChangeCallbackArgumentCaptor.capture());
240         ActiveModeWarden.ModeChangeCallback modeChangeCallback =
241                         mModeChangeCallbackArgumentCaptor.getValue();
242         ConcreteClientModeManager concreteClientModeManager = mock(ConcreteClientModeManager.class);
243         when(concreteClientModeManager.getInterfaceName()).thenReturn(TEST_IFACE_NAME);
244         when(concreteClientModeManager.getRole()).thenReturn(ActiveModeManager.ROLE_CLIENT_PRIMARY);
245         modeChangeCallback.onActiveModeManagerAdded(concreteClientModeManager);
246 
247         mSession = ExtendedMockito.mockitoSession()
248                 .strictness(Strictness.LENIENT)
249                 .mockStatic(WifiStatsLog.class)
250                 .startMocking();
251     }
252 
253     @After
tearDown()254     public void tearDown() {
255         mSession.finishMocking();
256     }
257 
258     /**
259      * Test that startConnectionEvent and endConnectionEvent can be called repeatedly and out of
260      * order. Only tests no exception occurs. Creates 3 ConnectionEvents.
261      */
262     @Test
startAndEndConnectionEventSucceeds()263     public void startAndEndConnectionEventSucceeds() throws Exception {
264         //Start and end Connection event
265         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
266                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
267         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
268                 WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
269                 WifiMetricsProto.ConnectionEvent.HLF_DHCP,
270                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
271         //end Connection event without starting one
272         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
273                 WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
274                 WifiMetricsProto.ConnectionEvent.HLF_DHCP,
275                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
276         //start two ConnectionEvents in a row
277         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
278                 "BLUE", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
279         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
280                 "GREEN", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
281     }
282 
283     private static final long TEST_RECORD_DURATION_SEC = 12 * 60 * 60;
284     private static final long TEST_RECORD_DURATION_MILLIS = TEST_RECORD_DURATION_SEC * 1000;
285     /**
286      * Simulate how dumpsys gets the proto from mWifiMetrics, filter the proto bytes out and
287      * deserialize them into mDecodedProto
288      */
dumpProtoAndDeserialize()289     private void dumpProtoAndDeserialize() throws Exception {
290         ByteArrayOutputStream stream = new ByteArrayOutputStream();
291         PrintWriter writer = new PrintWriter(stream);
292 
293         when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_RECORD_DURATION_MILLIS);
294         //Test proto dump, by passing in proto arg option
295         String[] args = {WifiMetrics.PROTO_DUMP_ARG};
296         mWifiMetrics.dump(null, writer, args);
297         writer.flush();
298         Pattern pattern = Pattern.compile(
299                 "(?<=WifiMetrics:\\n)([\\s\\S]*)(?=EndWifiMetrics)");
300         Matcher matcher = pattern.matcher(stream.toString());
301         assertTrue("Proto Byte string found in WifiMetrics.dump():\n" + stream.toString(),
302                 matcher.find());
303         String protoByteString = matcher.group(1);
304         byte[] protoBytes = Base64.decode(protoByteString, Base64.DEFAULT);
305         mDecodedProto = WifiMetricsProto.WifiLog.parseFrom(protoBytes);
306     }
307 
308     /*, LOCAL_GEN, DEAUTH_REASON*
309      * Gets the 'clean dump' proto bytes from mWifiMetrics & deserializes it into
310      * mDecodedProto
311      */
cleanDumpProtoAndDeserialize()312     public void cleanDumpProtoAndDeserialize() throws Exception {
313         ByteArrayOutputStream stream = new ByteArrayOutputStream();
314         PrintWriter writer = new PrintWriter(stream);
315 
316         when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_RECORD_DURATION_MILLIS);
317         //Test proto dump, by passing in proto arg option
318         String[] args = {WifiMetrics.PROTO_DUMP_ARG, WifiMetrics.CLEAN_DUMP_ARG};
319         mWifiMetrics.dump(null, writer, args);
320         writer.flush();
321         String protoByteString = stream.toString();
322         byte[] protoBytes = Base64.decode(protoByteString, Base64.DEFAULT);
323         mDecodedProto = WifiMetricsProto.WifiLog.parseFrom(protoBytes);
324     }
325 
326     /** Verifies that dump() includes the expected header */
327     @Test
stateDumpIncludesHeader()328     public void stateDumpIncludesHeader() throws Exception {
329         assertStringContains(getStateDump(), "WifiMetrics");
330     }
331 
332     /** Verifies that dump() includes correct alert count when there are no alerts. */
333     @Test
stateDumpAlertCountIsCorrectWithNoAlerts()334     public void stateDumpAlertCountIsCorrectWithNoAlerts() throws Exception {
335         assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=()");
336     }
337 
338     /** Verifies that dump() includes correct alert count when there is one alert. */
339     @Test
stateDumpAlertCountIsCorrectWithOneAlert()340     public void stateDumpAlertCountIsCorrectWithOneAlert() throws Exception {
341         mWifiMetrics.logFirmwareAlert(TEST_IFACE_NAME, 1);
342         assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=(1,1)");
343     }
344 
345     /** Verifies that dump() includes correct alert count when there are multiple alerts. */
346     @Test
stateDumpAlertCountIsCorrectWithMultipleAlerts()347     public void stateDumpAlertCountIsCorrectWithMultipleAlerts() throws Exception {
348         mWifiMetrics.logFirmwareAlert(TEST_IFACE_NAME, 1);
349         mWifiMetrics.logFirmwareAlert(TEST_IFACE_NAME, 1);
350         mWifiMetrics.logFirmwareAlert(TEST_IFACE_NAME, 16);
351         assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=(1,2),(16,1)");
352     }
353 
354     @Test
testDumpProtoAndDeserialize()355     public void testDumpProtoAndDeserialize() throws Exception {
356         setAndIncrementMetrics();
357         dumpProtoAndDeserialize();
358         verify(mWifiP2pMetrics).consolidateProto();
359         assertDeserializedMetricsCorrect();
360     }
361 
362     private static final int NUM_OPEN_NETWORKS = 2;
363     private static final int NUM_LEGACY_PERSONAL_NETWORKS = 3;
364     private static final int NUM_LEGACY_ENTERPRISE_NETWORKS = 5;
365     private static final int NUM_ENHANCED_OPEN_NETWORKS = 1;
366     private static final int NUM_WPA3_PERSONAL_NETWORKS = 4;
367     private static final int NUM_WPA3_ENTERPRISE_NETWORKS = 6;
368     private static final int NUM_WAPI_PERSONAL_NETWORKS = 4;
369     private static final int NUM_WAPI_ENTERPRISE_NETWORKS = 6;
370     private static final int NUM_SAVED_NETWORKS = NUM_OPEN_NETWORKS + NUM_LEGACY_PERSONAL_NETWORKS
371             + NUM_LEGACY_ENTERPRISE_NETWORKS + NUM_ENHANCED_OPEN_NETWORKS
372             + NUM_WPA3_PERSONAL_NETWORKS + NUM_WPA3_ENTERPRISE_NETWORKS
373             + NUM_WAPI_PERSONAL_NETWORKS + NUM_WAPI_ENTERPRISE_NETWORKS;
374     private static final int NUM_HIDDEN_NETWORKS = NUM_OPEN_NETWORKS;
375     private static final int NUM_PASSPOINT_NETWORKS = NUM_LEGACY_ENTERPRISE_NETWORKS;
376     private static final int NUM_NETWORKS_ADDED_BY_USER = 0;
377     private static final int NUM_NETWORKS_ADDED_BY_APPS = NUM_SAVED_NETWORKS
378             - NUM_NETWORKS_ADDED_BY_USER;
379     private static final boolean TEST_VAL_IS_LOCATION_ENABLED = true;
380     private static final boolean IS_SCANNING_ALWAYS_ENABLED = true;
381     private static final boolean IS_VERBOSE_LOGGING_ENABLED = true;
382     private static final boolean IS_ENHANCED_MAC_RANDOMIZATION_FORCE_ENABLED = true;
383     private static final boolean IS_WIFI_WAKE_ENABLED = true;
384     private static final int NUM_EMPTY_SCAN_RESULTS = 19;
385     private static final int NUM_NON_EMPTY_SCAN_RESULTS = 23;
386     private static final int NUM_SCAN_UNKNOWN = 1;
387     private static final int NUM_SCAN_SUCCESS = 2;
388     private static final int NUM_SCAN_FAILURE_INTERRUPTED = 3;
389     private static final int NUM_SCAN_FAILURE_INVALID_CONFIGURATION = 5;
390     private static final int NUM_WIFI_UNKNOWN_SCREEN_OFF = 3;
391     private static final int NUM_WIFI_UNKNOWN_SCREEN_ON = 5;
392     private static final int NUM_WIFI_ASSOCIATED_SCREEN_OFF = 7;
393     private static final int NUM_WIFI_ASSOCIATED_SCREEN_ON = 11;
394     private static final int NUM_CONNECTIVITY_WATCHDOG_PNO_GOOD = 11;
395     private static final int NUM_CONNECTIVITY_WATCHDOG_PNO_BAD = 12;
396     private static final int NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_GOOD = 13;
397     private static final int NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_BAD = 14;
398     private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS = 1;
399     private static final int NUM_LAST_RESORT_WATCHDOG_BAD_ASSOCIATION_NETWORKS_TOTAL = 2;
400     private static final int NUM_LAST_RESORT_WATCHDOG_BAD_AUTHENTICATION_NETWORKS_TOTAL = 3;
401     private static final int NUM_LAST_RESORT_WATCHDOG_BAD_DHCP_NETWORKS_TOTAL = 4;
402     private static final int NUM_LAST_RESORT_WATCHDOG_BAD_OTHER_NETWORKS_TOTAL = 5;
403     private static final int NUM_LAST_RESORT_WATCHDOG_AVAILABLE_NETWORKS_TOTAL = 6;
404     private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_ASSOCIATION = 7;
405     private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_AUTHENTICATION = 8;
406     private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_DHCP = 9;
407     private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_OTHER = 10;
408     private static final int NUM_LAST_RESORT_WATCHDOG_SUCCESSES = 5;
409     private static final int WATCHDOG_TOTAL_CONNECTION_FAILURE_COUNT_AFTER_TRIGGER = 6;
410     private static final int RSSI_POLL_FREQUENCY = 5150;
411     private static final int NUM_RSSI_LEVELS_TO_INCREMENT = 20;
412     private static final int NUM_OPEN_NETWORK_SCAN_RESULTS = 1;
413     private static final int NUM_LEGACY_PERSONAL_NETWORK_SCAN_RESULTS = 4;
414     private static final int NUM_ENHANCED_OPEN_NETWORK_SCAN_RESULTS = 1;
415     private static final int NUM_WPA3_PERSONAL_NETWORK_SCAN_RESULTS = 2;
416     private static final int NUM_WPA3_ENTERPRISE_NETWORK_SCAN_RESULTS = 3;
417     private static final int NUM_WAPI_PERSONAL_NETWORK_SCAN_RESULTS = 1;
418     private static final int NUM_WAPI_ENTERPRISE_NETWORK_SCAN_RESULTS = 2;
419     private static final int NUM_HIDDEN_NETWORK_SCAN_RESULTS = 1;
420     private static final int NUM_HOTSPOT2_R1_NETWORK_SCAN_RESULTS = 1;
421     private static final int NUM_HOTSPOT2_R2_NETWORK_SCAN_RESULTS = 2;
422     private static final int NUM_HOTSPOT2_R3_NETWORK_SCAN_RESULTS = 2;
423     private static final int NUM_LEGACY_ENTERPRISE_NETWORK_SCAN_RESULTS =
424             NUM_HOTSPOT2_R1_NETWORK_SCAN_RESULTS + NUM_HOTSPOT2_R2_NETWORK_SCAN_RESULTS
425             + NUM_HOTSPOT2_R3_NETWORK_SCAN_RESULTS;
426     private static final int NUM_SCANS = 5;
427     private static final int NUM_CONNECTIVITY_ONESHOT_SCAN_EVENT = 4;
428     private static final int NUM_EXTERNAL_APP_ONESHOT_SCAN_REQUESTS = 15;
429     private static final int NUM_EXTERNAL_FOREGROUND_APP_ONESHOT_SCAN_REQUESTS_THROTTLED = 10;
430     private static final int NUM_EXTERNAL_BACKGROUND_APP_ONESHOT_SCAN_REQUESTS_THROTTLED = 16;
431     // Look at buildMockScanDetailList, this number needs to match the mocked results
432     private static final int NUM_TOTAL_SCAN_RESULTS = NUM_OPEN_NETWORK_SCAN_RESULTS
433             + NUM_LEGACY_PERSONAL_NETWORK_SCAN_RESULTS + NUM_LEGACY_ENTERPRISE_NETWORK_SCAN_RESULTS
434             + NUM_ENHANCED_OPEN_NETWORK_SCAN_RESULTS + NUM_WPA3_PERSONAL_NETWORK_SCAN_RESULTS
435             + NUM_WPA3_ENTERPRISE_NETWORK_SCAN_RESULTS + NUM_WAPI_PERSONAL_NETWORK_SCAN_RESULTS
436             + NUM_WAPI_ENTERPRISE_NETWORK_SCAN_RESULTS;
437     private static final int MIN_RSSI_LEVEL = -127;
438     private static final int MAX_RSSI_LEVEL = 0;
439     private static final int WIFI_SCORE_RANGE_MIN = 0;
440     private static final int NUM_WIFI_SCORES_TO_INCREMENT = 20;
441     private static final int WIFI_SCORE_RANGE_MAX = 60;
442     private static final int NUM_OUT_OF_BOUND_ENTRIES = 10;
443     private static final int MAX_NUM_SOFTAP_RETURN_CODES = 3;
444     private static final int NUM_SOFTAP_START_SUCCESS = 3;
445     private static final int NUM_SOFTAP_FAILED_GENERAL_ERROR = 2;
446     private static final int NUM_SOFTAP_FAILED_NO_CHANNEL = 1;
447     private static final int NUM_HAL_CRASHES = 11;
448     private static final int NUM_WIFICOND_CRASHES = 12;
449     private static final int NUM_SUPPLICANT_CRASHES = 23;
450     private static final int NUM_HOSTAPD_CRASHES = 7;
451     private static final int NUM_WIFI_ON_FAILURE_DUE_TO_HAL = 13;
452     private static final int NUM_WIFI_ON_FAILURE_DUE_TO_WIFICOND = 14;
453     private static final int NUM_WIFI_ON_FAILURE_DUE_TO_SUPPLICANT = 20;
454     private static final int NUM_SOFTAP_ON_FAILURE_DUE_TO_HAL = 23;
455     private static final int NUM_SOFTAP_ON_FAILURE_DUE_TO_WIFICOND = 19;
456     private static final int NUM_SOFTAP_ON_FAILURE_DUE_TO_HOSTAPD = 31;
457     private static final int NUM_SOFTAP_INTERFACE_DOWN = 65;
458     private static final int NUM_CLIENT_INTERFACE_DOWN = 12;
459     private static final int NUM_PASSPOINT_PROVIDERS = 7;
460     private static final int NUM_PASSPOINT_PROVIDER_INSTALLATION = 5;
461     private static final int NUM_PASSPOINT_PROVIDER_INSTALL_SUCCESS = 4;
462     private static final int NUM_PASSPOINT_PROVIDER_UNINSTALLATION = 3;
463     private static final int NUM_PASSPOINT_PROVIDER_UNINSTALL_SUCCESS = 2;
464     private static final int NUM_PASSPOINT_PROVIDERS_SUCCESSFULLY_CONNECTED = 1;
465     private static final int NUM_PASSPOINT_PROVIDERS_WITH_NO_ROOT_CA = 2;
466     private static final int NUM_PASSPOINT_PROVIDERS_WITH_SELF_SIGNED_ROOT_CA = 3;
467     private static final int NUM_PASSPOINT_PROVIDERS_WITH_EXPIRATION_DATE = 4;
468     private static final int NUM_EAP_SIM_TYPE = 1;
469     private static final int NUM_EAP_TTLS_TYPE = 2;
470     private static final int NUM_EAP_TLS_TYPE = 3;
471     private static final int NUM_EAP_AKA_TYPE = 4;
472     private static final int NUM_EAP_AKA_PRIME_TYPE = 5;
473     private static final SparseIntArray SAVED_PASSPOINT_PROVIDERS_TYPE = new SparseIntArray();
474     static {
SAVED_PASSPOINT_PROVIDERS_TYPE.put(EAPConstants.EAP_SIM, NUM_EAP_SIM_TYPE)475         SAVED_PASSPOINT_PROVIDERS_TYPE.put(EAPConstants.EAP_SIM, NUM_EAP_SIM_TYPE);
SAVED_PASSPOINT_PROVIDERS_TYPE.put(EAPConstants.EAP_TTLS, NUM_EAP_TTLS_TYPE)476         SAVED_PASSPOINT_PROVIDERS_TYPE.put(EAPConstants.EAP_TTLS, NUM_EAP_TTLS_TYPE);
SAVED_PASSPOINT_PROVIDERS_TYPE.put(EAPConstants.EAP_TLS, NUM_EAP_TLS_TYPE)477         SAVED_PASSPOINT_PROVIDERS_TYPE.put(EAPConstants.EAP_TLS, NUM_EAP_TLS_TYPE);
SAVED_PASSPOINT_PROVIDERS_TYPE.put(EAPConstants.EAP_AKA, NUM_EAP_AKA_TYPE)478         SAVED_PASSPOINT_PROVIDERS_TYPE.put(EAPConstants.EAP_AKA, NUM_EAP_AKA_TYPE);
SAVED_PASSPOINT_PROVIDERS_TYPE.put(EAPConstants.EAP_AKA_PRIME, NUM_EAP_AKA_PRIME_TYPE)479         SAVED_PASSPOINT_PROVIDERS_TYPE.put(EAPConstants.EAP_AKA_PRIME, NUM_EAP_AKA_PRIME_TYPE);
480     }
481 
482     private static final int NUM_PARTIAL_SCAN_RESULTS = 73;
483     private static final int NUM_PNO_SCAN_ATTEMPTS = 20;
484     private static final int NUM_PNO_SCAN_FAILED = 5;
485     private static final int NUM_PNO_FOUND_NETWORK_EVENTS = 10;
486     private static final int NUM_RADIO_MODE_CHANGE_TO_MCC = 4;
487     private static final int NUM_RADIO_MODE_CHANGE_TO_SCC = 13;
488     private static final int NUM_RADIO_MODE_CHANGE_TO_SBS = 19;
489     private static final int NUM_RADIO_MODE_CHANGE_TO_DBS = 34;
490     private static final int NUM_SOFTAP_USER_BAND_PREFERENCE_UNSATISFIED = 14;
491     private static final long NUM_WATCHDOG_SUCCESS_DURATION_MS = 65;
492     private static final long WIFI_POWER_METRICS_LOGGING_DURATION = 280;
493     private static final long WIFI_POWER_METRICS_SCAN_TIME = 33;
494     private static final boolean WIFI_IS_UNUSABLE_EVENT_LOGGING_SETTING = true;
495     private static final boolean LINK_SPEED_COUNTS_LOGGING_SETTING = true;
496     private static final int DATA_STALL_MIN_TX_BAD_SETTING = 5;
497     private static final int DATA_STALL_MIN_TX_SUCCESS_WITHOUT_RX_SETTING = 75;
498     private static final int NUM_ONESHOT_SCAN_REQUESTS_WITH_DFS_CHANNELS = 4;
499     private static final int NUM_ADD_OR_UPDATE_NETWORK_CALLS = 5;
500     private static final int NUM_ENABLE_NETWORK_CALLS = 6;
501     private static final long NUM_IP_RENEWAL_FAILURE = 7;
502     private static final int NUM_NETWORK_ABNORMAL_ASSOC_REJECTION = 2;
503     private static final int NUM_NETWORK_ABNORMAL_CONNECTION_FAILURE_DISCONNECTION = 5;
504     private static final int NUM_NETWORK_SUFFICIENT_RECENT_STATS_ONLY = 4;
505     private static final int NUM_NETWORK_SUFFICIENT_RECENT_PREV_STATS = 5;
506     private static final int NUM_BSSID_SELECTION_DIFFERENT_BETWEEN_FRAMEWORK_FIRMWARE = 3;
507     private static final long WIFI_MAINLINE_MODULE_VERSION = 123456L;
508 
509     /** Number of notifications per "Connect to Network" notification type. */
510     private static final int[] NUM_CONNECT_TO_NETWORK_NOTIFICATIONS = {0, 10, 20, 30, 40};
511     /** Number of notifications per "Connect to Network notification type and action type. */
512     private static final int[][] NUM_CONNECT_TO_NETWORK_NOTIFICATION_ACTIONS = {
513             {0, 1, 2, 3, 4},
514             {10, 11, 12, 13, 14},
515             {20, 21, 22, 23, 24},
516             {30, 31, 32, 33, 34},
517             {40, 41, 42, 43, 44}};
518     private static final int SIZE_OPEN_NETWORK_RECOMMENDER_BLOCKLIST = 10;
519     private static final boolean IS_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = true;
520     private static final int NUM_OPEN_NETWORK_CONNECT_MESSAGE_FAILED_TO_SEND = 5;
521     private static final int NUM_OPEN_NETWORK_RECOMMENDATION_UPDATES = 8;
522     private static final String OPEN_NET_NOTIFIER_TAG = OpenNetworkNotifier.TAG;
523 
524     private static final int NUM_SOFT_AP_EVENT_ENTRIES = 3;
525     private static final int NUM_SOFT_AP_EVENT_ENTRIES_FOR_BRIDGED_AP = 4;
526     private static final int NUM_SOFT_AP_ASSOCIATED_STATIONS = 3;
527     private static final int SOFT_AP_CHANNEL_FREQUENCY_2G = 2437;
528     private static final int SOFT_AP_CHANNEL_BANDWIDTH_2G =
529             SoftApConnectedClientsEvent.BANDWIDTH_20;
530     private static final int SOFT_AP_GENERATION_2G = ScanResult.WIFI_STANDARD_11N;
531     private static final int SOFT_AP_CHANNEL_FREQUENCY_5G = 5180;
532     private static final int SOFT_AP_CHANNEL_BANDWIDTH_5G =
533             SoftApConnectedClientsEvent.BANDWIDTH_80;
534     private static final int SOFT_AP_GENERATION_5G = ScanResult.WIFI_STANDARD_11AC;
535     private static final int SOFT_AP_MAX_CLIENT_SETTING = 10;
536     private static final int SOFT_AP_MAX_CLIENT_CAPABILITY = 16;
537     private static final long SOFT_AP_SHUTDOWN_TIMEOUT_SETTING = 10_000;
538     private static final long SOFT_AP_SHUTDOWN_TIMEOUT_DEFAULT_SETTING = 600_000;
539     private static final boolean SOFT_AP_CLIENT_CONTROL_ENABLE = true;
540     private static final boolean IS_MAC_RANDOMIZATION_ON = true;
541     private static final int NUM_LINK_SPEED_LEVELS_TO_INCREMENT = 30;
542     private static final int TEST_RSSI_LEVEL = -80;
543     private static final int MAX_SUPPORTED_TX_LINK_SPEED_MBPS = 144;
544     private static final int MAX_SUPPORTED_RX_LINK_SPEED_MBPS = 190;
545 
546     private static final long NUM_MBO_SUPPORTED_NETWORKS_SCAN_RESULTS = 4;
547     private static final long NUM_MBO_CELL_DATA_AWARE_NETWORKS_SCAN_RESULTS = 2;
548     private static final long NUM_OCE_SUPPORTED_NETWORKS_SCAN_RESULTS = 2;
549     private static final long NUM_FILS_SUPPORTED_NETWORKS_SCAN_RESULTS = 2;
550     private static final long NUM_11AX_NETWORKS_SCAN_RESULTS = 3;
551     private static final long NUM_6G_NETWORKS_SCAN_RESULTS = 2;
552     private static final long NUM_6G_PSC_NETWORKS_SCAN_RESULTS = 1;
553     private static final long NUM_BSSID_FILTERED_DUE_TO_MBO_ASSOC_DISALLOW_IND = 3;
554     private static final long NUM_CONNECT_TO_MBO_SUPPORTED_NETWORKS = 4;
555     private static final long NUM_CONNECT_TO_OCE_SUPPORTED_NETWORKS = 3;
556     private static final long NUM_STEERING_REQUEST = 3;
557     private static final long NUM_FORCE_SCAN_DUE_TO_STEERING_REQUEST = 2;
558     private static final long NUM_MBO_CELLULAR_SWITCH_REQUEST = 3;
559     private static final long NUM_STEERING_REQUEST_INCLUDING_MBO_ASSOC_RETRY_DELAY = 3;
560     private static final long NUM_CONNECT_REQUEST_WITH_FILS_AKM = 4;
561     private static final long NUM_L2_CONNECTION_THROUGH_FILS_AUTHENTICATION = 3;
562 
563     private static final int FEATURE_MBO = 1 << 0;
564     private static final int FEATURE_MBO_CELL_DATA_AWARE = 1 << 1;
565     private static final int FEATURE_OCE = 1 << 2;
566     private static final int FEATURE_11AX = 1 << 3;
567     private static final int FEATURE_6G = 1 << 4;
568     private static final int FEATURE_6G_PSC = 1 << 5;
569 
buildMockScanDetail(boolean hidden, NetworkDetail.HSRelease hSRelease, String capabilities, int supportedFeatures)570     private ScanDetail buildMockScanDetail(boolean hidden, NetworkDetail.HSRelease hSRelease,
571             String capabilities, int supportedFeatures) {
572         ScanDetail mockScanDetail = mock(ScanDetail.class);
573         NetworkDetail mockNetworkDetail = mock(NetworkDetail.class);
574         ScanResult mockScanResult = mock(ScanResult.class);
575         when(mockScanDetail.getNetworkDetail()).thenReturn(mockNetworkDetail);
576         when(mockScanDetail.getScanResult()).thenReturn(mockScanResult);
577         when(mockNetworkDetail.isHiddenBeaconFrame()).thenReturn(hidden);
578         when(mockNetworkDetail.getHSRelease()).thenReturn(hSRelease);
579         mockScanResult.capabilities = capabilities;
580         if ((supportedFeatures & FEATURE_MBO) != 0) {
581             when(mockNetworkDetail.isMboSupported()).thenReturn(true);
582         }
583         if ((supportedFeatures & FEATURE_MBO_CELL_DATA_AWARE) != 0) {
584             when(mockNetworkDetail.isMboCellularDataAware()).thenReturn(true);
585         }
586         if ((supportedFeatures & FEATURE_OCE) != 0) {
587             when(mockNetworkDetail.isOceSupported()).thenReturn(true);
588         }
589         if ((supportedFeatures & FEATURE_11AX) != 0) {
590             when(mockNetworkDetail.getWifiMode())
591                     .thenReturn(InformationElementUtil.WifiMode.MODE_11AX);
592         }
593         if ((supportedFeatures & FEATURE_6G) != 0) {
594             when(mockScanResult.is6GHz()).thenReturn(true);
595         }
596         if ((supportedFeatures & FEATURE_6G_PSC) != 0) {
597             when(mockScanResult.is6GhzPsc()).thenReturn(true);
598         }
599         return mockScanDetail;
600     }
601 
buildMockScanDetail(String ssid, String bssid, boolean isOpen, boolean isSaved, boolean isProvider, boolean isWeakRssi)602     private ScanDetail buildMockScanDetail(String ssid, String bssid, boolean isOpen,
603             boolean isSaved, boolean isProvider, boolean isWeakRssi) {
604         ScanDetail mockScanDetail = mock(ScanDetail.class);
605         NetworkDetail mockNetworkDetail = mock(NetworkDetail.class);
606         ScanResult scanResult = new ScanResult();
607         scanResult.SSID = ssid;
608         scanResult.BSSID = bssid;
609         when(mockScanDetail.getNetworkDetail()).thenReturn(mockNetworkDetail);
610         when(mockScanDetail.getScanResult()).thenReturn(scanResult);
611         when(mWns.isSignalTooWeak(eq(scanResult))).thenReturn(isWeakRssi);
612         scanResult.capabilities = isOpen ? "" : "PSK";
613         if (isSaved) {
614             when(mWcm.getSavedNetworkForScanDetail(eq(mockScanDetail)))
615                     .thenReturn(mock(WifiConfiguration.class));
616         }
617         if (isProvider) {
618             PasspointProvider provider = mock(PasspointProvider.class);
619             List<Pair<PasspointProvider, PasspointMatch>> matchedProviders = new ArrayList<>();
620             matchedProviders.add(Pair.create(provider, null));
621             when(mockNetworkDetail.isInterworking()).thenReturn(true);
622             when(mPpm.matchProvider(eq(scanResult), eq(false))).thenReturn(matchedProviders);
623         }
624         return mockScanDetail;
625     }
626 
buildMockScanDetailPasspoint(String ssid, String bssid, long hessid, int anqpDomainId, NetworkDetail.HSRelease hsRelease, boolean weakSignal)627     private ScanDetail buildMockScanDetailPasspoint(String ssid, String bssid, long hessid,
628             int anqpDomainId, NetworkDetail.HSRelease hsRelease, boolean weakSignal) {
629         ScanDetail mockScanDetail = mock(ScanDetail.class);
630         NetworkDetail mockNetworkDetail = mock(NetworkDetail.class);
631         ScanResult scanResult = new ScanResult();
632         scanResult.SSID = ssid;
633         scanResult.BSSID = bssid;
634         scanResult.hessid = hessid;
635         scanResult.capabilities = "PSK";
636         when(mockScanDetail.getNetworkDetail()).thenReturn(mockNetworkDetail);
637         when(mockScanDetail.getScanResult()).thenReturn(scanResult);
638         when(mockNetworkDetail.getHSRelease()).thenReturn(hsRelease);
639         when(mockNetworkDetail.getAnqpDomainID()).thenReturn(anqpDomainId);
640         when(mockNetworkDetail.isInterworking()).thenReturn(true);
641         when(mWns.isSignalTooWeak(eq(scanResult))).thenReturn(weakSignal);
642         return mockScanDetail;
643     }
644 
buildMockScanDetailList()645     private List<ScanDetail> buildMockScanDetailList() {
646         List<ScanDetail> mockScanDetails = new ArrayList<ScanDetail>();
647         mockScanDetails.add(buildMockScanDetail(true, null, "[ESS]", 0));
648         mockScanDetails.add(buildMockScanDetail(false, null, "[WPA2-PSK-CCMP][ESS]", FEATURE_11AX));
649         mockScanDetails.add(buildMockScanDetail(false, null, "[WPA-PSK-CCMP]", 0));
650         mockScanDetails.add(buildMockScanDetail(false, null, "[WPA2-SAE-CCMP]", FEATURE_MBO));
651         mockScanDetails.add(buildMockScanDetail(false, null, "[WPA-PSK-CCMP]",
652                 FEATURE_11AX | FEATURE_6G));
653         mockScanDetails.add(buildMockScanDetail(false, null, "[WEP]", 0));
654         mockScanDetails.add(buildMockScanDetail(false, null, "[WPA2-SAE-CCMP]",
655                 FEATURE_MBO | FEATURE_MBO_CELL_DATA_AWARE));
656         mockScanDetails.add(buildMockScanDetail(false, null, "[WPA2-OWE-CCMP]",
657                 FEATURE_MBO | FEATURE_MBO_CELL_DATA_AWARE | FEATURE_OCE));
658         mockScanDetails.add(buildMockScanDetail(false, null, "[RSN-SUITE_B_192][MFPR]",
659                 FEATURE_11AX | FEATURE_6G | FEATURE_6G_PSC));
660         // WPA3 Enterprise transition network
661         mockScanDetails.add(buildMockScanDetail(false, null,
662                 "[RSN-EAP/SHA1+EAP/SHA256-CCMP][MFPC]", 0));
663         // WPA3 Enterprise only network
664         mockScanDetails.add(buildMockScanDetail(false, null,
665                 "[RSN-EAP/SHA256-CCMP][MFPR][MFPC]", 0));
666         mockScanDetails.add(buildMockScanDetail(false, null, "[WAPI-WAPI-PSK-SMS4-SMS4]", 0));
667         mockScanDetails.add(buildMockScanDetail(false, null, "[WAPI-WAPI-CERT-SMS4-SMS4]", 0));
668         mockScanDetails.add(buildMockScanDetail(false, null, "[WAPI-WAPI-CERT-SMS4-SMS4]", 0));
669         // Number of scans of R2 networks must be equal to NUM_HOTSPOT2_R2_NETWORK_SCAN_RESULTS
670         mockScanDetails.add(buildMockScanDetail(false, NetworkDetail.HSRelease.R2,
671                 "[WPA-EAP/SHA1-CCMP+EAP-FILS-SHA256-CCMP]", FEATURE_MBO | FEATURE_OCE));
672         mockScanDetails.add(buildMockScanDetail(false, NetworkDetail.HSRelease.R2,
673                 "[WPA2-EAP/SHA1+FT/EAP-CCMP+EAP-FILS-SHA256-CCMP]", 0));
674         // Number of scans of R1 networks must be equal to NUM_HOTSPOT2_R1_NETWORK_SCAN_RESULTS
675         mockScanDetails.add(buildMockScanDetail(false, NetworkDetail.HSRelease.R1,
676                 "[WPA-EAP/SHA1-CCMP]", 0));
677         // Number of scans of R3 networks must be equal to NUM_HOTSPOT2_R3_NETWORK_SCAN_RESULTS
678         mockScanDetails.add(buildMockScanDetail(false, NetworkDetail.HSRelease.R3,
679                 "[WPA-EAP/SHA1-CCMP]", 0));
680         // WPA2 Enterprise network with MFPR and MFPC
681         mockScanDetails.add(buildMockScanDetail(false, NetworkDetail.HSRelease.R3,
682                 "[WPA-EAP/SHA1-CCMP][MFPR][MFPC]", 0));
683         return mockScanDetails;
684     }
685 
buildSavedNetworkList()686     private List<WifiConfiguration> buildSavedNetworkList() {
687         List<WifiConfiguration> testSavedNetworks = new ArrayList<WifiConfiguration>();
688         for (int i = 0; i < NUM_OPEN_NETWORKS; i++) {
689             testSavedNetworks.add(WifiConfigurationTestUtil.createOpenHiddenNetwork());
690         }
691         for (int i = 0; i < NUM_LEGACY_PERSONAL_NETWORKS; i++) {
692             testSavedNetworks.add(WifiConfigurationTestUtil.createPskNetwork());
693         }
694         for (int i = 0; i < NUM_LEGACY_ENTERPRISE_NETWORKS; i++) {
695             // Passpoint networks are counted in both Passpoint and Enterprise counters
696             testSavedNetworks.add(WifiConfigurationTestUtil.createPasspointNetwork());
697         }
698         for (int i = 0; i < NUM_ENHANCED_OPEN_NETWORKS; i++) {
699             testSavedNetworks.add(WifiConfigurationTestUtil.createOweNetwork());
700         }
701         for (int i = 0; i < NUM_WPA3_PERSONAL_NETWORKS; i++) {
702             testSavedNetworks.add(WifiConfigurationTestUtil.createSaeNetwork());
703         }
704         for (int i = 0; i < NUM_WPA3_ENTERPRISE_NETWORKS; i++) {
705             testSavedNetworks.add(WifiConfigurationTestUtil.createEapSuiteBNetwork());
706         }
707         for (int i = 0; i < NUM_WAPI_PERSONAL_NETWORKS; i++) {
708             testSavedNetworks.add(WifiConfigurationTestUtil.createWapiPskNetwork());
709         }
710         for (int i = 0; i < NUM_WAPI_ENTERPRISE_NETWORKS; i++) {
711             testSavedNetworks.add(WifiConfigurationTestUtil.createWapiCertNetwork());
712         }
713         testSavedNetworks.get(0).macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
714         return testSavedNetworks;
715     }
716 
createMockProvider(int eapType, boolean validateForR2)717     private PasspointProvider createMockProvider(int eapType, boolean validateForR2) {
718         PasspointProvider provider = mock(PasspointProvider.class);
719         PasspointConfiguration config = mock(PasspointConfiguration.class);
720         Credential credential = new Credential();
721 
722         switch (eapType) {
723             case EAPConstants.EAP_TLS:
724                 credential.setCertCredential(new Credential.CertificateCredential());
725                 break;
726             case EAPConstants.EAP_TTLS:
727                 credential.setUserCredential(new Credential.UserCredential());
728                 break;
729             case EAPConstants.EAP_AKA:
730             case EAPConstants.EAP_AKA_PRIME:
731             case EAPConstants.EAP_SIM:
732                 Credential.SimCredential simCredential = new Credential.SimCredential();
733                 simCredential.setEapType(eapType);
734                 credential.setSimCredential(simCredential);
735                 break;
736         }
737         when(provider.getConfig()).thenReturn(config);
738         when(config.getCredential()).thenReturn(credential);
739         when(config.validateForR2()).thenReturn(validateForR2);
740         return provider;
741     }
742 
743     /**
744      * Set simple metrics, increment others
745      */
setAndIncrementMetrics()746     public void setAndIncrementMetrics() throws Exception {
747         Map<String, PasspointProvider> providers = new HashMap<>();
748         mWifiMetrics.updateSavedNetworks(buildSavedNetworkList());
749         mWifiMetrics.updateSavedPasspointProfiles(NUM_PASSPOINT_PROVIDERS,
750                 NUM_PASSPOINT_PROVIDERS_SUCCESSFULLY_CONNECTED);
751         for (int i = 0; i < SAVED_PASSPOINT_PROVIDERS_TYPE.size(); i++) {
752             int eapType = SAVED_PASSPOINT_PROVIDERS_TYPE.keyAt(i);
753             int count = SAVED_PASSPOINT_PROVIDERS_TYPE.valueAt(i);
754             for (int j = 0; j < count; j++) {
755                 providers.put(Integer.toString(eapType) + j, createMockProvider(eapType, false));
756             }
757             for (int j = count; j < count * 2; j++) {
758                 providers.put(Integer.toString(eapType) + j, createMockProvider(eapType, true));
759             }
760         }
761         mWifiMetrics.updateSavedPasspointProfilesInfo(providers);
762 
763         mWifiMetrics.setIsLocationEnabled(TEST_VAL_IS_LOCATION_ENABLED);
764         mWifiMetrics.setIsScanningAlwaysEnabled(IS_SCANNING_ALWAYS_ENABLED);
765         mWifiMetrics.setVerboseLoggingEnabled(IS_VERBOSE_LOGGING_ENABLED);
766         mWifiMetrics.setEnhancedMacRandomizationForceEnabled(
767                 IS_ENHANCED_MAC_RANDOMIZATION_FORCE_ENABLED);
768         mWifiMetrics.setWifiWakeEnabled(IS_WIFI_WAKE_ENABLED);
769 
770         for (int i = 0; i < NUM_EMPTY_SCAN_RESULTS; i++) {
771             mWifiMetrics.incrementEmptyScanResultCount();
772         }
773         for (int i = 0; i < NUM_NON_EMPTY_SCAN_RESULTS; i++) {
774             mWifiMetrics.incrementNonEmptyScanResultCount();
775         }
776         mWifiMetrics.incrementScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_UNKNOWN,
777                 NUM_SCAN_UNKNOWN);
778         mWifiMetrics.incrementScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS,
779                 NUM_SCAN_SUCCESS);
780         mWifiMetrics.incrementScanReturnEntry(
781                 WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED,
782                 NUM_SCAN_FAILURE_INTERRUPTED);
783         mWifiMetrics.incrementScanReturnEntry(
784                 WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION,
785                 NUM_SCAN_FAILURE_INVALID_CONFIGURATION);
786         for (int i = 0; i < NUM_WIFI_UNKNOWN_SCREEN_OFF; i++) {
787             mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN,
788                     false);
789         }
790         for (int i = 0; i < NUM_WIFI_UNKNOWN_SCREEN_ON; i++) {
791             mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN,
792                     true);
793         }
794         for (int i = 0; i < NUM_WIFI_ASSOCIATED_SCREEN_OFF; i++) {
795             mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED,
796                     false);
797         }
798         for (int i = 0; i < NUM_WIFI_ASSOCIATED_SCREEN_ON; i++) {
799             mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED,
800                     true);
801         }
802         for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_PNO_GOOD; i++) {
803             mWifiMetrics.incrementNumConnectivityWatchdogPnoGood();
804         }
805         for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_PNO_BAD; i++) {
806             mWifiMetrics.incrementNumConnectivityWatchdogPnoBad();
807         }
808         for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_GOOD; i++) {
809             mWifiMetrics.incrementNumConnectivityWatchdogBackgroundGood();
810         }
811         for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_BAD; i++) {
812             mWifiMetrics.incrementNumConnectivityWatchdogBackgroundBad();
813         }
814         for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS; i++) {
815             mWifiMetrics.incrementNumLastResortWatchdogTriggers();
816         }
817         mWifiMetrics.addCountToNumLastResortWatchdogBadAssociationNetworksTotal(
818                 NUM_LAST_RESORT_WATCHDOG_BAD_ASSOCIATION_NETWORKS_TOTAL);
819         mWifiMetrics.addCountToNumLastResortWatchdogBadAuthenticationNetworksTotal(
820                 NUM_LAST_RESORT_WATCHDOG_BAD_AUTHENTICATION_NETWORKS_TOTAL);
821         mWifiMetrics.addCountToNumLastResortWatchdogBadDhcpNetworksTotal(
822                 NUM_LAST_RESORT_WATCHDOG_BAD_DHCP_NETWORKS_TOTAL);
823         mWifiMetrics.addCountToNumLastResortWatchdogBadOtherNetworksTotal(
824                 NUM_LAST_RESORT_WATCHDOG_BAD_OTHER_NETWORKS_TOTAL);
825         mWifiMetrics.addCountToNumLastResortWatchdogAvailableNetworksTotal(
826                 NUM_LAST_RESORT_WATCHDOG_AVAILABLE_NETWORKS_TOTAL);
827         for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_ASSOCIATION; i++) {
828             mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadAssociation();
829         }
830         for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_AUTHENTICATION; i++) {
831             mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadAuthentication();
832         }
833         for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_DHCP; i++) {
834             mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadDhcp();
835         }
836         for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_OTHER; i++) {
837             mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadOther();
838         }
839         for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_SUCCESSES; i++) {
840             mWifiMetrics.incrementNumLastResortWatchdogSuccesses();
841         }
842         for (int i = 0; i < WATCHDOG_TOTAL_CONNECTION_FAILURE_COUNT_AFTER_TRIGGER; i++) {
843             mWifiMetrics.incrementWatchdogTotalConnectionFailureCountAfterTrigger();
844         }
845         for (int i = 0; i < NUM_RSSI_LEVELS_TO_INCREMENT; i++) {
846             for (int j = 0; j <= i; j++) {
847                 mWifiMetrics.incrementRssiPollRssiCount(RSSI_POLL_FREQUENCY, MIN_RSSI_LEVEL + i);
848             }
849         }
850         for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
851             mWifiMetrics.incrementRssiPollRssiCount(RSSI_POLL_FREQUENCY, MIN_RSSI_LEVEL - i);
852         }
853         for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
854             mWifiMetrics.incrementRssiPollRssiCount(RSSI_POLL_FREQUENCY, MAX_RSSI_LEVEL + i);
855         }
856 
857         // Test alert-reason clamping.
858         mWifiMetrics.logFirmwareAlert(TEST_IFACE_NAME, WifiLoggerHal.WIFI_ALERT_REASON_MIN - 1);
859         mWifiMetrics.logFirmwareAlert(TEST_IFACE_NAME, WifiLoggerHal.WIFI_ALERT_REASON_MAX + 1);
860         // Simple cases for alert reason.
861         mWifiMetrics.logFirmwareAlert(TEST_IFACE_NAME, 1);
862         mWifiMetrics.logFirmwareAlert(TEST_IFACE_NAME, 1);
863         mWifiMetrics.logFirmwareAlert(TEST_IFACE_NAME, 1);
864         mWifiMetrics.logFirmwareAlert(TEST_IFACE_NAME, 2);
865         List<ScanDetail> mockScanDetails = buildMockScanDetailList();
866         for (int i = 0; i < NUM_SCANS; i++) {
867             mWifiMetrics.countScanResults(mockScanDetails);
868         }
869         // increment connectivity scan metrics
870         for (int i = 0; i < NUM_CONNECTIVITY_ONESHOT_SCAN_EVENT; i++) {
871             mWifiMetrics.incrementConnectivityOneshotScanCount();
872         }
873         for (int i = 0; i < NUM_EXTERNAL_APP_ONESHOT_SCAN_REQUESTS; i++) {
874             mWifiMetrics.incrementExternalAppOneshotScanRequestsCount();
875         }
876         for (int i = 0; i < NUM_EXTERNAL_FOREGROUND_APP_ONESHOT_SCAN_REQUESTS_THROTTLED; i++) {
877             mWifiMetrics.incrementExternalForegroundAppOneshotScanRequestsThrottledCount();
878         }
879         for (int i = 0; i < NUM_EXTERNAL_BACKGROUND_APP_ONESHOT_SCAN_REQUESTS_THROTTLED; i++) {
880             mWifiMetrics.incrementExternalBackgroundAppOneshotScanRequestsThrottledCount();
881         }
882         for (int score = 0; score < NUM_WIFI_SCORES_TO_INCREMENT; score++) {
883             for (int offset = 0; offset <= score; offset++) {
884                 mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, WIFI_SCORE_RANGE_MIN + score);
885             }
886         }
887         for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
888             mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, WIFI_SCORE_RANGE_MIN - i);
889         }
890         for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
891             mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, WIFI_SCORE_RANGE_MAX + i);
892         }
893         for (int score = 0; score < NUM_WIFI_SCORES_TO_INCREMENT; score++) {
894             for (int offset = 0; offset <= score; offset++) {
895                 mWifiMetrics.incrementWifiUsabilityScoreCount(
896                         TEST_IFACE_NAME, 1, WIFI_SCORE_RANGE_MIN + score, 15);
897             }
898         }
899         for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
900             mWifiMetrics.incrementWifiUsabilityScoreCount(
901                     TEST_IFACE_NAME, 1, WIFI_SCORE_RANGE_MIN - i, 15);
902         }
903         for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
904             mWifiMetrics.incrementWifiUsabilityScoreCount(
905                     TEST_IFACE_NAME, 1, WIFI_SCORE_RANGE_MAX + i, 15);
906         }
907 
908         // increment soft ap start return codes
909         for (int i = 0; i < NUM_SOFTAP_START_SUCCESS; i++) {
910             mWifiMetrics.incrementSoftApStartResult(true, 0);
911         }
912         for (int i = 0; i < NUM_SOFTAP_FAILED_GENERAL_ERROR; i++) {
913             mWifiMetrics.incrementSoftApStartResult(false, WifiManager.SAP_START_FAILURE_GENERAL);
914         }
915         for (int i = 0; i < NUM_SOFTAP_FAILED_NO_CHANNEL; i++) {
916             mWifiMetrics.incrementSoftApStartResult(false,
917                     WifiManager.SAP_START_FAILURE_NO_CHANNEL);
918         }
919         for (int i = 0; i < NUM_HAL_CRASHES; i++) {
920             mWifiMetrics.incrementNumHalCrashes();
921         }
922         for (int i = 0; i < NUM_WIFICOND_CRASHES; i++) {
923             mWifiMetrics.incrementNumWificondCrashes();
924         }
925         for (int i = 0; i < NUM_SUPPLICANT_CRASHES; i++) {
926             mWifiMetrics.incrementNumSupplicantCrashes();
927         }
928         for (int i = 0; i < NUM_HOSTAPD_CRASHES; i++) {
929             mWifiMetrics.incrementNumHostapdCrashes();
930         }
931         for (int i = 0; i < NUM_WIFI_ON_FAILURE_DUE_TO_HAL; i++) {
932             mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToHal();
933         }
934         for (int i = 0; i < NUM_WIFI_ON_FAILURE_DUE_TO_WIFICOND; i++) {
935             mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToWificond();
936         }
937         for (int i = 0; i < NUM_WIFI_ON_FAILURE_DUE_TO_SUPPLICANT; i++) {
938             mWifiMetrics.incrementNumSetupClientInterfaceFailureDueToSupplicant();
939         }
940         for (int i = 0; i < NUM_SOFTAP_ON_FAILURE_DUE_TO_HAL; i++) {
941             mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToHal();
942         }
943         for (int i = 0; i < NUM_SOFTAP_ON_FAILURE_DUE_TO_WIFICOND; i++) {
944             mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToWificond();
945         }
946         for (int i = 0; i < NUM_SOFTAP_ON_FAILURE_DUE_TO_HOSTAPD; i++) {
947             mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToHostapd();
948         }
949         for (int i = 0; i < NUM_SOFTAP_INTERFACE_DOWN; i++) {
950             mWifiMetrics.incrementNumSoftApInterfaceDown();
951         }
952         for (int i = 0; i < NUM_CLIENT_INTERFACE_DOWN; i++) {
953             mWifiMetrics.incrementNumClientInterfaceDown();
954         }
955         for (int i = 0; i < NUM_PASSPOINT_PROVIDER_INSTALLATION; i++) {
956             mWifiMetrics.incrementNumPasspointProviderInstallation();
957         }
958         for (int i = 0; i < NUM_PASSPOINT_PROVIDER_INSTALL_SUCCESS; i++) {
959             mWifiMetrics.incrementNumPasspointProviderInstallSuccess();
960         }
961         for (int i = 0; i < NUM_PASSPOINT_PROVIDER_UNINSTALLATION; i++) {
962             mWifiMetrics.incrementNumPasspointProviderUninstallation();
963         }
964         for (int i = 0; i < NUM_PASSPOINT_PROVIDER_UNINSTALL_SUCCESS; i++) {
965             mWifiMetrics.incrementNumPasspointProviderUninstallSuccess();
966         }
967         for (int i = 0; i < NUM_PASSPOINT_PROVIDERS_WITH_NO_ROOT_CA; i++) {
968             mWifiMetrics.incrementNumPasspointProviderWithNoRootCa();
969         }
970         for (int i = 0; i < NUM_PASSPOINT_PROVIDERS_WITH_SELF_SIGNED_ROOT_CA; i++) {
971             mWifiMetrics.incrementNumPasspointProviderWithSelfSignedRootCa();
972         }
973         for (int i = 0; i < NUM_PASSPOINT_PROVIDERS_WITH_EXPIRATION_DATE; i++) {
974             mWifiMetrics.incrementNumPasspointProviderWithSubscriptionExpiration();
975         }
976         for (int i = 0; i < NUM_RADIO_MODE_CHANGE_TO_MCC; i++) {
977             mWifiMetrics.incrementNumRadioModeChangeToMcc();
978         }
979         for (int i = 0; i < NUM_RADIO_MODE_CHANGE_TO_SCC; i++) {
980             mWifiMetrics.incrementNumRadioModeChangeToScc();
981         }
982         for (int i = 0; i < NUM_RADIO_MODE_CHANGE_TO_SBS; i++) {
983             mWifiMetrics.incrementNumRadioModeChangeToSbs();
984         }
985         for (int i = 0; i < NUM_RADIO_MODE_CHANGE_TO_DBS; i++) {
986             mWifiMetrics.incrementNumRadioModeChangeToDbs();
987         }
988         for (int i = 0; i < NUM_SOFTAP_USER_BAND_PREFERENCE_UNSATISFIED; i++) {
989             mWifiMetrics.incrementNumSoftApUserBandPreferenceUnsatisfied();
990         }
991 
992         // increment pno scan metrics
993         for (int i = 0; i < NUM_PNO_SCAN_ATTEMPTS; i++) {
994             mWifiMetrics.incrementPnoScanStartAttemptCount();
995         }
996         for (int i = 0; i < NUM_PNO_SCAN_FAILED; i++) {
997             mWifiMetrics.incrementPnoScanFailedCount();
998         }
999         for (int i = 0; i < NUM_PNO_FOUND_NETWORK_EVENTS; i++) {
1000             mWifiMetrics.incrementPnoFoundNetworkEventCount();
1001         }
1002         for (int i = 0; i < NUM_BSSID_SELECTION_DIFFERENT_BETWEEN_FRAMEWORK_FIRMWARE; i++) {
1003             mWifiMetrics.incrementNumBssidDifferentSelectionBetweenFrameworkAndFirmware();
1004         }
1005 
1006         // set and increment "connect to network" notification metrics
1007         for (int i = 0; i < NUM_CONNECT_TO_NETWORK_NOTIFICATIONS.length; i++) {
1008             int count = NUM_CONNECT_TO_NETWORK_NOTIFICATIONS[i];
1009             for (int j = 0; j < count; j++) {
1010                 mWifiMetrics.incrementConnectToNetworkNotification(OPEN_NET_NOTIFIER_TAG, i);
1011             }
1012         }
1013         for (int i = 0; i < NUM_CONNECT_TO_NETWORK_NOTIFICATION_ACTIONS.length; i++) {
1014             int[] actions = NUM_CONNECT_TO_NETWORK_NOTIFICATION_ACTIONS[i];
1015             for (int j = 0; j < actions.length; j++) {
1016                 int count = actions[j];
1017                 for (int k = 0; k < count; k++) {
1018                     mWifiMetrics.incrementConnectToNetworkNotificationAction(OPEN_NET_NOTIFIER_TAG,
1019                             i, j);
1020                 }
1021             }
1022         }
1023         mWifiMetrics.setNetworkRecommenderBlocklistSize(OPEN_NET_NOTIFIER_TAG,
1024                 SIZE_OPEN_NETWORK_RECOMMENDER_BLOCKLIST);
1025         mWifiMetrics.setIsWifiNetworksAvailableNotificationEnabled(OPEN_NET_NOTIFIER_TAG,
1026                 IS_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON);
1027         for (int i = 0; i < NUM_OPEN_NETWORK_RECOMMENDATION_UPDATES; i++) {
1028             mWifiMetrics.incrementNumNetworkRecommendationUpdates(OPEN_NET_NOTIFIER_TAG);
1029         }
1030         for (int i = 0; i < NUM_OPEN_NETWORK_CONNECT_MESSAGE_FAILED_TO_SEND; i++) {
1031             mWifiMetrics.incrementNumNetworkConnectMessageFailedToSend(OPEN_NET_NOTIFIER_TAG);
1032         }
1033 
1034         addSoftApEventsToMetrics();
1035 
1036         for (int i = 0; i < NUM_ONESHOT_SCAN_REQUESTS_WITH_DFS_CHANNELS; i++) {
1037             mWifiMetrics.incrementOneshotScanWithDfsCount();
1038         }
1039         for (int i = 0; i < NUM_ADD_OR_UPDATE_NETWORK_CALLS; i++) {
1040             mWifiMetrics.incrementNumAddOrUpdateNetworkCalls();
1041         }
1042         for (int i = 0; i < NUM_ENABLE_NETWORK_CALLS; i++) {
1043             mWifiMetrics.incrementNumEnableNetworkCalls();
1044         }
1045         for (int i = 0; i < NUM_IP_RENEWAL_FAILURE; i++) {
1046             mWifiMetrics.incrementIpRenewalFailure();
1047         }
1048 
1049         mWifiMetrics.setWatchdogSuccessTimeDurationMs(NUM_WATCHDOG_SUCCESS_DURATION_MS);
1050         mResources.setBoolean(R.bool.config_wifi_connected_mac_randomization_supported,
1051                 IS_MAC_RANDOMIZATION_ON);
1052 
1053         addWifiPowerMetrics();
1054 
1055         addWifiHealthMetrics();
1056 
1057         mResources.setBoolean(R.bool.config_wifiIsUnusableEventMetricsEnabled,
1058                 WIFI_IS_UNUSABLE_EVENT_LOGGING_SETTING);
1059         mResources.setBoolean(R.bool.config_wifiLinkSpeedMetricsEnabled,
1060                 LINK_SPEED_COUNTS_LOGGING_SETTING);
1061         mResources.setInteger(R.integer.config_wifiDataStallMinTxBad,
1062                 DATA_STALL_MIN_TX_BAD_SETTING);
1063         mResources.setInteger(R.integer.config_wifiDataStallMinTxSuccessWithoutRx,
1064                 DATA_STALL_MIN_TX_SUCCESS_WITHOUT_RX_SETTING);
1065 
1066         for (int i = 0; i < NUM_BSSID_FILTERED_DUE_TO_MBO_ASSOC_DISALLOW_IND; i++) {
1067             mWifiMetrics.incrementNetworkSelectionFilteredBssidCountDueToMboAssocDisallowInd();
1068         }
1069         for (int i = 0; i < NUM_STEERING_REQUEST; i++) {
1070             mWifiMetrics.incrementSteeringRequestCount();
1071         }
1072         for (int i = 0; i < NUM_FORCE_SCAN_DUE_TO_STEERING_REQUEST; i++) {
1073             mWifiMetrics.incrementForceScanCountDueToSteeringRequest();
1074         }
1075         for (int i = 0; i < NUM_MBO_CELLULAR_SWITCH_REQUEST; i++) {
1076             mWifiMetrics.incrementMboCellularSwitchRequestCount();
1077         }
1078         for (int i = 0; i < NUM_STEERING_REQUEST_INCLUDING_MBO_ASSOC_RETRY_DELAY; i++) {
1079             mWifiMetrics.incrementSteeringRequestCountIncludingMboAssocRetryDelay();
1080         }
1081         for (int i = 0; i < NUM_CONNECT_REQUEST_WITH_FILS_AKM; i++) {
1082             mWifiMetrics.incrementConnectRequestWithFilsAkmCount();
1083         }
1084         for (int i = 0; i < NUM_L2_CONNECTION_THROUGH_FILS_AUTHENTICATION; i++) {
1085             mWifiMetrics.incrementL2ConnectionThroughFilsAuthCount();
1086         }
1087     }
1088 
addWifiPowerMetrics()1089     private void addWifiPowerMetrics() {
1090         WifiRadioUsage wifiRadioUsage = new WifiRadioUsage();
1091         wifiRadioUsage.loggingDurationMs = WIFI_POWER_METRICS_LOGGING_DURATION;
1092         wifiRadioUsage.scanTimeMs = WIFI_POWER_METRICS_SCAN_TIME;
1093         when(mWifiPowerMetrics.buildWifiRadioUsageProto()).thenReturn(wifiRadioUsage);
1094     }
1095 
addWifiHealthMetrics()1096     private void addWifiHealthMetrics() {
1097         HealthMonitorMetrics metrics = new HealthMonitorMetrics();
1098         metrics.failureStatsIncrease = new HealthMonitorFailureStats();
1099         metrics.failureStatsDecrease = new HealthMonitorFailureStats();
1100         metrics.failureStatsHigh = new HealthMonitorFailureStats();
1101         metrics.failureStatsIncrease.cntAssocRejection = NUM_NETWORK_ABNORMAL_ASSOC_REJECTION;
1102         metrics.failureStatsDecrease.cntDisconnectionNonlocalConnecting =
1103                 NUM_NETWORK_ABNORMAL_CONNECTION_FAILURE_DISCONNECTION;
1104         metrics.numNetworkSufficientRecentStatsOnly = NUM_NETWORK_SUFFICIENT_RECENT_STATS_ONLY;
1105         metrics.numNetworkSufficientRecentPrevStats = NUM_NETWORK_SUFFICIENT_RECENT_PREV_STATS;
1106         when(mWifiHealthMonitor.buildProto()).thenReturn(metrics);
1107         when(mWifiHealthMonitor.getWifiStackVersion()).thenReturn(WIFI_MAINLINE_MODULE_VERSION);
1108     }
1109 
addSoftApEventsToMetrics()1110     private void addSoftApEventsToMetrics() {
1111         SoftApInfo testSoftApInfo_2G = new SoftApInfo();
1112         testSoftApInfo_2G.setFrequency(SOFT_AP_CHANNEL_FREQUENCY_2G);
1113         testSoftApInfo_2G.setBandwidth(SOFT_AP_CHANNEL_BANDWIDTH_2G);
1114         testSoftApInfo_2G.setWifiStandard(SOFT_AP_GENERATION_2G);
1115         SoftApInfo testSoftApInfo_5G = new SoftApInfo();
1116         testSoftApInfo_5G.setFrequency(SOFT_AP_CHANNEL_FREQUENCY_5G);
1117         testSoftApInfo_5G.setBandwidth(SOFT_AP_CHANNEL_BANDWIDTH_5G);
1118         testSoftApInfo_5G.setWifiStandard(SOFT_AP_GENERATION_5G);
1119 
1120         // Total number of events recorded is NUM_SOFT_AP_EVENT_ENTRIES in both modes
1121         mWifiMetrics.addSoftApUpChangedEvent(true, WifiManager.IFACE_IP_MODE_TETHERED,
1122                 SOFT_AP_SHUTDOWN_TIMEOUT_DEFAULT_SETTING, false);
1123         mWifiMetrics.addSoftApNumAssociatedStationsChangedEvent(NUM_SOFT_AP_ASSOCIATED_STATIONS,
1124                 NUM_SOFT_AP_ASSOCIATED_STATIONS, WifiManager.IFACE_IP_MODE_TETHERED,
1125                 testSoftApInfo_2G);
1126 
1127         // Should be dropped.
1128         mWifiMetrics.addSoftApNumAssociatedStationsChangedEvent(NUM_SOFT_AP_ASSOCIATED_STATIONS,
1129                 NUM_SOFT_AP_ASSOCIATED_STATIONS, WifiManager.IFACE_IP_MODE_UNSPECIFIED,
1130                 testSoftApInfo_2G);
1131 
1132         mWifiMetrics.addSoftApUpChangedEvent(false, WifiManager.IFACE_IP_MODE_TETHERED,
1133                 SOFT_AP_SHUTDOWN_TIMEOUT_DEFAULT_SETTING, false);
1134 
1135 
1136 
1137         // Channel switch info should be added to the last Soft AP UP event in the list
1138         mWifiMetrics.addSoftApChannelSwitchedEvent(new ArrayList<>() {{ add(testSoftApInfo_2G); }},
1139                 WifiManager.IFACE_IP_MODE_TETHERED, false);
1140         SoftApConfiguration testSoftApConfig = new SoftApConfiguration.Builder()
1141                 .setSsid("Test_Metric_SSID")
1142                 .setMaxNumberOfClients(SOFT_AP_MAX_CLIENT_SETTING)
1143                 .setShutdownTimeoutMillis(SOFT_AP_SHUTDOWN_TIMEOUT_SETTING)
1144                 .setClientControlByUserEnabled(SOFT_AP_CLIENT_CONTROL_ENABLE)
1145                 .build();
1146         mWifiMetrics.updateSoftApConfiguration(testSoftApConfig,
1147                 WifiManager.IFACE_IP_MODE_TETHERED, false);
1148         SoftApCapability testSoftApCapability = new SoftApCapability(0);
1149         testSoftApCapability.setMaxSupportedClients(SOFT_AP_MAX_CLIENT_CAPABILITY);
1150         mWifiMetrics.updateSoftApCapability(testSoftApCapability,
1151                 WifiManager.IFACE_IP_MODE_TETHERED, false);
1152 
1153         mWifiMetrics.addSoftApUpChangedEvent(true, WifiManager.IFACE_IP_MODE_LOCAL_ONLY,
1154                 SOFT_AP_SHUTDOWN_TIMEOUT_DEFAULT_SETTING, false);
1155         mWifiMetrics.addSoftApNumAssociatedStationsChangedEvent(NUM_SOFT_AP_ASSOCIATED_STATIONS,
1156                 NUM_SOFT_AP_ASSOCIATED_STATIONS, WifiManager.IFACE_IP_MODE_LOCAL_ONLY,
1157                 testSoftApInfo_2G);
1158 
1159         // Should be dropped.
1160         mWifiMetrics.addSoftApUpChangedEvent(false, WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR,
1161                 SOFT_AP_SHUTDOWN_TIMEOUT_DEFAULT_SETTING, false);
1162         mWifiMetrics.addSoftApUpChangedEvent(false, WifiManager.IFACE_IP_MODE_LOCAL_ONLY,
1163                 SOFT_AP_SHUTDOWN_TIMEOUT_DEFAULT_SETTING, false);
1164 
1165         // Bridged mode test, total NUM_SOFT_AP_EVENT_ENTRIES_FOR_BRIDGED_AP events for bridged mode
1166         mWifiMetrics.addSoftApUpChangedEvent(true, WifiManager.IFACE_IP_MODE_TETHERED,
1167                 SOFT_AP_SHUTDOWN_TIMEOUT_DEFAULT_SETTING, true);
1168         mWifiMetrics.addSoftApChannelSwitchedEvent(new ArrayList<>() {{
1169                     add(testSoftApInfo_2G);
1170                     add(testSoftApInfo_5G);
1171                 }},
1172                 WifiManager.IFACE_IP_MODE_TETHERED, true);
1173 
1174         mWifiMetrics.updateSoftApConfiguration(testSoftApConfig,
1175                 WifiManager.IFACE_IP_MODE_TETHERED, true);
1176         mWifiMetrics.updateSoftApCapability(testSoftApCapability,
1177                 WifiManager.IFACE_IP_MODE_TETHERED, true);
1178 
1179         mWifiMetrics.addSoftApInstanceDownEventInDualMode(WifiManager.IFACE_IP_MODE_TETHERED,
1180                 testSoftApInfo_5G);
1181         mWifiMetrics.addSoftApUpChangedEvent(false, WifiManager.IFACE_IP_MODE_TETHERED,
1182                 SOFT_AP_SHUTDOWN_TIMEOUT_DEFAULT_SETTING, true);
1183     }
1184 
verifySoftApEventsStoredInProto()1185     private void verifySoftApEventsStoredInProto() {
1186         // Tethered mode includes single AP and dual AP test.
1187         assertEquals(NUM_SOFT_AP_EVENT_ENTRIES + NUM_SOFT_AP_EVENT_ENTRIES_FOR_BRIDGED_AP,
1188                 mDecodedProto.softApConnectedClientsEventsTethered.length);
1189         assertEquals(SoftApConnectedClientsEvent.SOFT_AP_UP,
1190                 mDecodedProto.softApConnectedClientsEventsTethered[0].eventType);
1191         assertEquals(0, mDecodedProto.softApConnectedClientsEventsTethered[0].numConnectedClients);
1192         assertEquals(SOFT_AP_CHANNEL_FREQUENCY_2G,
1193                 mDecodedProto.softApConnectedClientsEventsTethered[0].channelFrequency);
1194         assertEquals(SOFT_AP_CHANNEL_BANDWIDTH_2G,
1195                 mDecodedProto.softApConnectedClientsEventsTethered[0].channelBandwidth);
1196         assertEquals(SOFT_AP_MAX_CLIENT_SETTING,
1197                 mDecodedProto.softApConnectedClientsEventsTethered[0]
1198                 .maxNumClientsSettingInSoftapConfiguration);
1199         assertEquals(SOFT_AP_MAX_CLIENT_CAPABILITY,
1200                 mDecodedProto.softApConnectedClientsEventsTethered[0]
1201                 .maxNumClientsSettingInSoftapCapability);
1202         assertEquals(SOFT_AP_SHUTDOWN_TIMEOUT_SETTING,
1203                 mDecodedProto.softApConnectedClientsEventsTethered[0]
1204                 .shutdownTimeoutSettingInSoftapConfiguration);
1205         assertEquals(SOFT_AP_SHUTDOWN_TIMEOUT_DEFAULT_SETTING,
1206                 mDecodedProto.softApConnectedClientsEventsTethered[0]
1207                 .defaultShutdownTimeoutSetting);
1208         assertEquals(SOFT_AP_CLIENT_CONTROL_ENABLE,
1209                 mDecodedProto.softApConnectedClientsEventsTethered[0].clientControlIsEnabled);
1210 
1211         assertEquals(SoftApConnectedClientsEvent.NUM_CLIENTS_CHANGED,
1212                 mDecodedProto.softApConnectedClientsEventsTethered[1].eventType);
1213         assertEquals(NUM_SOFT_AP_ASSOCIATED_STATIONS,
1214                 mDecodedProto.softApConnectedClientsEventsTethered[1].numConnectedClients);
1215         assertEquals(SoftApConnectedClientsEvent.SOFT_AP_DOWN,
1216                 mDecodedProto.softApConnectedClientsEventsTethered[2].eventType);
1217         assertEquals(0, mDecodedProto.softApConnectedClientsEventsTethered[2].numConnectedClients);
1218 
1219         // Verify the bridged AP metrics
1220         assertEquals(SoftApConnectedClientsEvent.DUAL_AP_BOTH_INSTANCES_UP,
1221                 mDecodedProto.softApConnectedClientsEventsTethered[3].eventType);
1222         assertEquals(0, mDecodedProto.softApConnectedClientsEventsTethered[3].numConnectedClients);
1223         assertEquals(SOFT_AP_CHANNEL_FREQUENCY_2G,
1224                 mDecodedProto.softApConnectedClientsEventsTethered[3].channelFrequency);
1225         assertEquals(SOFT_AP_CHANNEL_BANDWIDTH_2G,
1226                 mDecodedProto.softApConnectedClientsEventsTethered[3].channelBandwidth);
1227         assertEquals(SOFT_AP_MAX_CLIENT_SETTING,
1228                 mDecodedProto.softApConnectedClientsEventsTethered[3]
1229                 .maxNumClientsSettingInSoftapConfiguration);
1230         assertEquals(SOFT_AP_MAX_CLIENT_CAPABILITY,
1231                 mDecodedProto.softApConnectedClientsEventsTethered[3]
1232                 .maxNumClientsSettingInSoftapCapability);
1233         assertEquals(SOFT_AP_SHUTDOWN_TIMEOUT_SETTING,
1234                 mDecodedProto.softApConnectedClientsEventsTethered[3]
1235                 .shutdownTimeoutSettingInSoftapConfiguration);
1236         assertEquals(SOFT_AP_SHUTDOWN_TIMEOUT_DEFAULT_SETTING,
1237                 mDecodedProto.softApConnectedClientsEventsTethered[3]
1238                 .defaultShutdownTimeoutSetting);
1239         assertEquals(SOFT_AP_CLIENT_CONTROL_ENABLE,
1240                 mDecodedProto.softApConnectedClientsEventsTethered[3].clientControlIsEnabled);
1241         assertEquals(SoftApConnectedClientsEvent.DUAL_AP_BOTH_INSTANCES_UP,
1242                 mDecodedProto.softApConnectedClientsEventsTethered[4].eventType);
1243         assertEquals(0, mDecodedProto.softApConnectedClientsEventsTethered[4].numConnectedClients);
1244         assertEquals(SOFT_AP_CHANNEL_FREQUENCY_5G,
1245                 mDecodedProto.softApConnectedClientsEventsTethered[4].channelFrequency);
1246         assertEquals(SOFT_AP_CHANNEL_BANDWIDTH_5G,
1247                 mDecodedProto.softApConnectedClientsEventsTethered[4].channelBandwidth);
1248         assertEquals(SOFT_AP_MAX_CLIENT_SETTING,
1249                 mDecodedProto.softApConnectedClientsEventsTethered[4]
1250                 .maxNumClientsSettingInSoftapConfiguration);
1251         assertEquals(SOFT_AP_MAX_CLIENT_CAPABILITY,
1252                 mDecodedProto.softApConnectedClientsEventsTethered[4]
1253                 .maxNumClientsSettingInSoftapCapability);
1254         assertEquals(SOFT_AP_SHUTDOWN_TIMEOUT_SETTING,
1255                 mDecodedProto.softApConnectedClientsEventsTethered[4]
1256                 .shutdownTimeoutSettingInSoftapConfiguration);
1257         assertEquals(SOFT_AP_SHUTDOWN_TIMEOUT_DEFAULT_SETTING,
1258                 mDecodedProto.softApConnectedClientsEventsTethered[4]
1259                 .defaultShutdownTimeoutSetting);
1260         assertEquals(SOFT_AP_CLIENT_CONTROL_ENABLE,
1261                 mDecodedProto.softApConnectedClientsEventsTethered[4].clientControlIsEnabled);
1262         assertEquals(SoftApConnectedClientsEvent.DUAL_AP_ONE_INSTANCE_DOWN,
1263                 mDecodedProto.softApConnectedClientsEventsTethered[5].eventType);
1264         assertEquals(0, mDecodedProto.softApConnectedClientsEventsTethered[5].numConnectedClients);
1265         assertEquals(SoftApConnectedClientsEvent.SOFT_AP_DOWN,
1266                 mDecodedProto.softApConnectedClientsEventsTethered[6].eventType);
1267         assertEquals(0, mDecodedProto.softApConnectedClientsEventsTethered[6].numConnectedClients);
1268 
1269         assertEquals(SoftApConnectedClientsEvent.SOFT_AP_UP,
1270                 mDecodedProto.softApConnectedClientsEventsLocalOnly[0].eventType);
1271         assertEquals(0, mDecodedProto.softApConnectedClientsEventsLocalOnly[0].numConnectedClients);
1272         assertEquals(SoftApConnectedClientsEvent.NUM_CLIENTS_CHANGED,
1273                 mDecodedProto.softApConnectedClientsEventsLocalOnly[1].eventType);
1274         assertEquals(NUM_SOFT_AP_ASSOCIATED_STATIONS,
1275                 mDecodedProto.softApConnectedClientsEventsLocalOnly[1].numConnectedClients);
1276         assertEquals(SoftApConnectedClientsEvent.SOFT_AP_DOWN,
1277                 mDecodedProto.softApConnectedClientsEventsLocalOnly[2].eventType);
1278         assertEquals(0, mDecodedProto.softApConnectedClientsEventsLocalOnly[2].numConnectedClients);
1279     }
1280 
1281     /**
1282      * Assert that values in deserializedWifiMetrics match those set in 'setAndIncrementMetrics'
1283      */
assertDeserializedMetricsCorrect()1284     private void assertDeserializedMetricsCorrect() throws Exception {
1285         assertEquals("mDecodedProto.numSavedNetworks == NUM_SAVED_NETWORKS",
1286                 NUM_SAVED_NETWORKS, mDecodedProto.numSavedNetworks);
1287         assertEquals("mDecodedProto.numSavedNetworksWithMacRandomization == NUM_SAVED_NETWORKS-1",
1288                 NUM_SAVED_NETWORKS - 1, mDecodedProto.numSavedNetworksWithMacRandomization);
1289         assertEquals("mDecodedProto.numOpenNetworks == NUM_OPEN_NETWORKS",
1290                 NUM_OPEN_NETWORKS, mDecodedProto.numOpenNetworks);
1291         assertEquals("mDecodedProto.numLegacyPersonalNetworks == NUM_LEGACY_PERSONAL_NETWORKS",
1292                 NUM_LEGACY_PERSONAL_NETWORKS, mDecodedProto.numLegacyPersonalNetworks);
1293         assertEquals(
1294                 "mDecodedProto.numLegacyEnterpriseNetworks == NUM_LEGACY_ENTERPRISE_NETWORKS",
1295                 NUM_LEGACY_ENTERPRISE_NETWORKS, mDecodedProto.numLegacyEnterpriseNetworks);
1296         assertEquals("mDecodedProto.numEnhancedOpenNetworks == NUM_ENHANCED_OPEN_NETWORKS",
1297                 NUM_ENHANCED_OPEN_NETWORKS, mDecodedProto.numEnhancedOpenNetworks);
1298         assertEquals("mDecodedProto.numWpa3PersonalNetworks == NUM_WPA3_PERSONAL_NETWORKS",
1299                 NUM_WPA3_PERSONAL_NETWORKS, mDecodedProto.numWpa3PersonalNetworks);
1300         assertEquals("mDecodedProto.numWpa3EnterpriseNetworks == NUM_WPA3_ENTERPRISE_NETWORKS",
1301                 NUM_WPA3_ENTERPRISE_NETWORKS, mDecodedProto.numWpa3EnterpriseNetworks);
1302         assertEquals("mDecodedProto.numWapiPersonalNetworks == NUM_WAPI_PERSONAL_NETWORKS",
1303                 NUM_WAPI_PERSONAL_NETWORKS, mDecodedProto.numWapiPersonalNetworks);
1304         assertEquals("mDecodedProto.numWapiEnterpriseNetworks == NUM_WAPI_ENTERPRISE_NETWORKS",
1305                 NUM_WAPI_ENTERPRISE_NETWORKS, mDecodedProto.numWapiEnterpriseNetworks);
1306         assertEquals("mDecodedProto.numNetworksAddedByUser == NUM_NETWORKS_ADDED_BY_USER",
1307                 NUM_NETWORKS_ADDED_BY_USER, mDecodedProto.numNetworksAddedByUser);
1308         assertEquals(NUM_HIDDEN_NETWORKS, mDecodedProto.numHiddenNetworks);
1309         assertEquals(NUM_PASSPOINT_NETWORKS, mDecodedProto.numPasspointNetworks);
1310         assertEquals("mDecodedProto.numNetworksAddedByApps == NUM_NETWORKS_ADDED_BY_APPS",
1311                 NUM_NETWORKS_ADDED_BY_APPS, mDecodedProto.numNetworksAddedByApps);
1312         assertEquals("mDecodedProto.isLocationEnabled == TEST_VAL_IS_LOCATION_ENABLED",
1313                 TEST_VAL_IS_LOCATION_ENABLED, mDecodedProto.isLocationEnabled);
1314         assertEquals("mDecodedProto.isScanningAlwaysEnabled == IS_SCANNING_ALWAYS_ENABLED",
1315                 IS_SCANNING_ALWAYS_ENABLED, mDecodedProto.isScanningAlwaysEnabled);
1316         assertEquals(IS_VERBOSE_LOGGING_ENABLED, mDecodedProto.isVerboseLoggingEnabled);
1317         assertEquals(IS_ENHANCED_MAC_RANDOMIZATION_FORCE_ENABLED,
1318                 mDecodedProto.isEnhancedMacRandomizationForceEnabled);
1319         assertEquals(IS_WIFI_WAKE_ENABLED, mDecodedProto.isWifiWakeEnabled);
1320         assertEquals("mDecodedProto.numEmptyScanResults == NUM_EMPTY_SCAN_RESULTS",
1321                 NUM_EMPTY_SCAN_RESULTS, mDecodedProto.numEmptyScanResults);
1322         assertEquals("mDecodedProto.numNonEmptyScanResults == NUM_NON_EMPTY_SCAN_RESULTS",
1323                 NUM_NON_EMPTY_SCAN_RESULTS, mDecodedProto.numNonEmptyScanResults);
1324         assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_UNKNOWN, NUM_SCAN_UNKNOWN);
1325         assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_SUCCESS, NUM_SCAN_SUCCESS);
1326         assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED,
1327                 NUM_SCAN_FAILURE_INTERRUPTED);
1328         assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION,
1329                 NUM_SCAN_FAILURE_INVALID_CONFIGURATION);
1330         assertSystemStateEntryEquals(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, false,
1331                 NUM_WIFI_UNKNOWN_SCREEN_OFF);
1332         assertSystemStateEntryEquals(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, true,
1333                 NUM_WIFI_UNKNOWN_SCREEN_ON);
1334         assertSystemStateEntryEquals(
1335                 WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, false, NUM_WIFI_ASSOCIATED_SCREEN_OFF);
1336         assertSystemStateEntryEquals(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, true,
1337                 NUM_WIFI_ASSOCIATED_SCREEN_ON);
1338         assertEquals(NUM_CONNECTIVITY_WATCHDOG_PNO_GOOD,
1339                 mDecodedProto.numConnectivityWatchdogPnoGood);
1340         assertEquals(NUM_CONNECTIVITY_WATCHDOG_PNO_BAD,
1341                 mDecodedProto.numConnectivityWatchdogPnoBad);
1342         assertEquals(NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_GOOD,
1343                 mDecodedProto.numConnectivityWatchdogBackgroundGood);
1344         assertEquals(NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_BAD,
1345                 mDecodedProto.numConnectivityWatchdogBackgroundBad);
1346         assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS,
1347                 mDecodedProto.numLastResortWatchdogTriggers);
1348         assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_ASSOCIATION_NETWORKS_TOTAL,
1349                 mDecodedProto.numLastResortWatchdogBadAssociationNetworksTotal);
1350         assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_AUTHENTICATION_NETWORKS_TOTAL,
1351                 mDecodedProto.numLastResortWatchdogBadAuthenticationNetworksTotal);
1352         assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_DHCP_NETWORKS_TOTAL,
1353                 mDecodedProto.numLastResortWatchdogBadDhcpNetworksTotal);
1354         assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_OTHER_NETWORKS_TOTAL,
1355                 mDecodedProto.numLastResortWatchdogBadOtherNetworksTotal);
1356         assertEquals(NUM_LAST_RESORT_WATCHDOG_AVAILABLE_NETWORKS_TOTAL,
1357                 mDecodedProto.numLastResortWatchdogAvailableNetworksTotal);
1358         assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_ASSOCIATION,
1359                 mDecodedProto.numLastResortWatchdogTriggersWithBadAssociation);
1360         assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_AUTHENTICATION,
1361                 mDecodedProto.numLastResortWatchdogTriggersWithBadAuthentication);
1362         assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_DHCP,
1363                 mDecodedProto.numLastResortWatchdogTriggersWithBadDhcp);
1364         assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_OTHER,
1365                 mDecodedProto.numLastResortWatchdogTriggersWithBadOther);
1366         assertEquals(NUM_LAST_RESORT_WATCHDOG_SUCCESSES,
1367                 mDecodedProto.numLastResortWatchdogSuccesses);
1368         assertEquals(WATCHDOG_TOTAL_CONNECTION_FAILURE_COUNT_AFTER_TRIGGER,
1369                 mDecodedProto.watchdogTotalConnectionFailureCountAfterTrigger);
1370         assertEquals(TEST_RECORD_DURATION_SEC,
1371                 mDecodedProto.recordDurationSec);
1372         for (int i = 0; i < NUM_RSSI_LEVELS_TO_INCREMENT; i++) {
1373             assertEquals(RSSI_POLL_FREQUENCY,
1374                     mDecodedProto.rssiPollRssiCount[i].frequency);
1375             assertEquals(MIN_RSSI_LEVEL + i, mDecodedProto.rssiPollRssiCount[i].rssi);
1376             assertEquals(i + 1, mDecodedProto.rssiPollRssiCount[i].count);
1377         }
1378         StringBuilder sb_rssi = new StringBuilder();
1379         sb_rssi.append("Number of RSSIs = " + mDecodedProto.rssiPollRssiCount.length);
1380         assertTrue(sb_rssi.toString(), (mDecodedProto.rssiPollRssiCount.length
1381                      <= (MAX_RSSI_LEVEL - MIN_RSSI_LEVEL + 1)));
1382         assertEquals(2, mDecodedProto.alertReasonCount[0].count);  // Clamped reasons.
1383         assertEquals(3, mDecodedProto.alertReasonCount[1].count);
1384         assertEquals(1, mDecodedProto.alertReasonCount[2].count);
1385         assertEquals(3, mDecodedProto.alertReasonCount.length);
1386         assertEquals(NUM_TOTAL_SCAN_RESULTS * NUM_SCANS,
1387                 mDecodedProto.numTotalScanResults);
1388         assertEquals(NUM_OPEN_NETWORK_SCAN_RESULTS * NUM_SCANS,
1389                 mDecodedProto.numOpenNetworkScanResults);
1390         assertEquals(NUM_LEGACY_PERSONAL_NETWORK_SCAN_RESULTS * NUM_SCANS,
1391                 mDecodedProto.numLegacyPersonalNetworkScanResults);
1392         assertEquals(NUM_LEGACY_ENTERPRISE_NETWORK_SCAN_RESULTS * NUM_SCANS,
1393                 mDecodedProto.numLegacyEnterpriseNetworkScanResults);
1394         assertEquals(NUM_ENHANCED_OPEN_NETWORK_SCAN_RESULTS * NUM_SCANS,
1395                 mDecodedProto.numEnhancedOpenNetworkScanResults);
1396         assertEquals(NUM_WPA3_PERSONAL_NETWORK_SCAN_RESULTS * NUM_SCANS,
1397                 mDecodedProto.numWpa3PersonalNetworkScanResults);
1398         assertEquals(NUM_WPA3_ENTERPRISE_NETWORK_SCAN_RESULTS * NUM_SCANS,
1399                 mDecodedProto.numWpa3EnterpriseNetworkScanResults);
1400         assertEquals(NUM_WAPI_PERSONAL_NETWORK_SCAN_RESULTS * NUM_SCANS,
1401                 mDecodedProto.numWapiPersonalNetworkScanResults);
1402         assertEquals(NUM_WAPI_ENTERPRISE_NETWORK_SCAN_RESULTS * NUM_SCANS,
1403                 mDecodedProto.numWapiEnterpriseNetworkScanResults);
1404         assertEquals(NUM_HIDDEN_NETWORK_SCAN_RESULTS * NUM_SCANS,
1405                 mDecodedProto.numHiddenNetworkScanResults);
1406         assertEquals(NUM_HOTSPOT2_R1_NETWORK_SCAN_RESULTS * NUM_SCANS,
1407                 mDecodedProto.numHotspot2R1NetworkScanResults);
1408         assertEquals(NUM_HOTSPOT2_R2_NETWORK_SCAN_RESULTS * NUM_SCANS,
1409                 mDecodedProto.numHotspot2R2NetworkScanResults);
1410         assertEquals(NUM_HOTSPOT2_R3_NETWORK_SCAN_RESULTS * NUM_SCANS,
1411                 mDecodedProto.numHotspot2R3NetworkScanResults);
1412 
1413         assertEquals(NUM_MBO_SUPPORTED_NETWORKS_SCAN_RESULTS * NUM_SCANS,
1414                 mDecodedProto.numMboSupportedNetworkScanResults);
1415         assertEquals(NUM_MBO_CELL_DATA_AWARE_NETWORKS_SCAN_RESULTS * NUM_SCANS,
1416                 mDecodedProto.numMboCellularDataAwareNetworkScanResults);
1417         assertEquals(NUM_OCE_SUPPORTED_NETWORKS_SCAN_RESULTS * NUM_SCANS,
1418                 mDecodedProto.numOceSupportedNetworkScanResults);
1419         assertEquals(NUM_FILS_SUPPORTED_NETWORKS_SCAN_RESULTS * NUM_SCANS,
1420                 mDecodedProto.numFilsSupportedNetworkScanResults);
1421         assertEquals(NUM_11AX_NETWORKS_SCAN_RESULTS * NUM_SCANS,
1422                 mDecodedProto.num11AxNetworkScanResults);
1423         assertEquals(NUM_6G_NETWORKS_SCAN_RESULTS * NUM_SCANS,
1424                 mDecodedProto.num6GNetworkScanResults);
1425         assertEquals(NUM_6G_PSC_NETWORKS_SCAN_RESULTS * NUM_SCANS,
1426                 mDecodedProto.num6GPscNetworkScanResults);
1427         assertEquals(NUM_SCANS,
1428                 mDecodedProto.numScans);
1429         assertEquals(NUM_CONNECTIVITY_ONESHOT_SCAN_EVENT,
1430                 mDecodedProto.numConnectivityOneshotScans);
1431         assertEquals(NUM_EXTERNAL_APP_ONESHOT_SCAN_REQUESTS,
1432                 mDecodedProto.numExternalAppOneshotScanRequests);
1433         assertEquals(NUM_EXTERNAL_FOREGROUND_APP_ONESHOT_SCAN_REQUESTS_THROTTLED,
1434                 mDecodedProto.numExternalForegroundAppOneshotScanRequestsThrottled);
1435         assertEquals(NUM_EXTERNAL_BACKGROUND_APP_ONESHOT_SCAN_REQUESTS_THROTTLED,
1436                 mDecodedProto.numExternalBackgroundAppOneshotScanRequestsThrottled);
1437 
1438         for (int score_index = 0; score_index < NUM_WIFI_SCORES_TO_INCREMENT; score_index++) {
1439             assertEquals(WIFI_SCORE_RANGE_MIN + score_index,
1440                     mDecodedProto.wifiScoreCount[score_index].score);
1441             assertEquals(WIFI_SCORE_RANGE_MIN + score_index + 1,
1442                     mDecodedProto.wifiScoreCount[score_index].count);
1443             assertEquals(WIFI_SCORE_RANGE_MIN + score_index,
1444                     mDecodedProto.wifiUsabilityScoreCount[score_index].score);
1445             assertEquals(WIFI_SCORE_RANGE_MIN + score_index + 1,
1446                     mDecodedProto.wifiUsabilityScoreCount[score_index].count);
1447         }
1448         StringBuilder sb_wifi_score = new StringBuilder();
1449         sb_wifi_score.append("Number of wifi_scores = " + mDecodedProto.wifiScoreCount.length);
1450         assertTrue(sb_wifi_score.toString(), (mDecodedProto.wifiScoreCount.length
1451                 <= (WIFI_SCORE_RANGE_MAX - WIFI_SCORE_RANGE_MIN + 1)));
1452         StringBuilder sb_wifi_limits = new StringBuilder();
1453         sb_wifi_limits.append("Wifi Score limit is " +  ConnectedScore.WIFI_MAX_SCORE
1454                 + ">= " + WIFI_SCORE_RANGE_MAX);
1455         assertTrue(sb_wifi_limits.toString(),
1456                 ConnectedScore.WIFI_MAX_SCORE <= WIFI_SCORE_RANGE_MAX);
1457         StringBuilder sb_wifi_usability_score = new StringBuilder();
1458         sb_wifi_usability_score.append("Number of wifi_usability_scores = "
1459                 + mDecodedProto.wifiUsabilityScoreCount.length);
1460         assertTrue(sb_wifi_usability_score.toString(), (mDecodedProto.wifiUsabilityScoreCount.length
1461                 <= (WIFI_SCORE_RANGE_MAX - WIFI_SCORE_RANGE_MIN + 1)));
1462         StringBuilder sb_wifi_usablity_limits = new StringBuilder();
1463         sb_wifi_limits.append("Wifi Usability Score limit is " +  ConnectedScore.WIFI_MAX_SCORE
1464                 + ">= " + WIFI_SCORE_RANGE_MAX);
1465         assertTrue(sb_wifi_limits.toString(),
1466                 ConnectedScore.WIFI_MAX_SCORE <= WIFI_SCORE_RANGE_MAX);
1467         assertEquals(MAX_NUM_SOFTAP_RETURN_CODES, mDecodedProto.softApReturnCode.length);
1468         assertEquals(WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_STARTED_SUCCESSFULLY,
1469                      mDecodedProto.softApReturnCode[0].startResult);
1470         assertEquals(NUM_SOFTAP_START_SUCCESS, mDecodedProto.softApReturnCode[0].count);
1471         assertEquals(WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_GENERAL_ERROR,
1472                      mDecodedProto.softApReturnCode[1].startResult);
1473         assertEquals(NUM_SOFTAP_FAILED_GENERAL_ERROR,
1474                      mDecodedProto.softApReturnCode[1].count);
1475         assertEquals(WifiMetricsProto.SoftApReturnCodeCount.SOFT_AP_FAILED_NO_CHANNEL,
1476                      mDecodedProto.softApReturnCode[2].startResult);
1477         assertEquals(NUM_SOFTAP_FAILED_NO_CHANNEL,
1478                      mDecodedProto.softApReturnCode[2].count);
1479         assertEquals(NUM_HAL_CRASHES, mDecodedProto.numHalCrashes);
1480         assertEquals(NUM_WIFICOND_CRASHES, mDecodedProto.numWificondCrashes);
1481         assertEquals(NUM_SUPPLICANT_CRASHES, mDecodedProto.numSupplicantCrashes);
1482         assertEquals(NUM_HOSTAPD_CRASHES, mDecodedProto.numHostapdCrashes);
1483         assertEquals(NUM_WIFI_ON_FAILURE_DUE_TO_HAL,
1484                 mDecodedProto.numSetupClientInterfaceFailureDueToHal);
1485         assertEquals(NUM_WIFI_ON_FAILURE_DUE_TO_WIFICOND,
1486                 mDecodedProto.numSetupClientInterfaceFailureDueToWificond);
1487         assertEquals(NUM_WIFI_ON_FAILURE_DUE_TO_SUPPLICANT,
1488                 mDecodedProto.numSetupClientInterfaceFailureDueToSupplicant);
1489         assertEquals(NUM_SOFTAP_ON_FAILURE_DUE_TO_HAL,
1490                 mDecodedProto.numSetupSoftApInterfaceFailureDueToHal);
1491         assertEquals(NUM_SOFTAP_ON_FAILURE_DUE_TO_WIFICOND,
1492                 mDecodedProto.numSetupSoftApInterfaceFailureDueToWificond);
1493         assertEquals(NUM_SOFTAP_ON_FAILURE_DUE_TO_HOSTAPD,
1494                 mDecodedProto.numSetupSoftApInterfaceFailureDueToHostapd);
1495         assertEquals(NUM_CLIENT_INTERFACE_DOWN, mDecodedProto.numClientInterfaceDown);
1496         assertEquals(NUM_SOFTAP_INTERFACE_DOWN, mDecodedProto.numSoftApInterfaceDown);
1497         assertEquals(NUM_PASSPOINT_PROVIDERS, mDecodedProto.numPasspointProviders);
1498         assertPasspointProfileTypeCount(mDecodedProto.installedPasspointProfileTypeForR1);
1499         assertPasspointProfileTypeCount(mDecodedProto.installedPasspointProfileTypeForR2);
1500         assertEquals(NUM_PASSPOINT_PROVIDER_INSTALLATION,
1501                 mDecodedProto.numPasspointProviderInstallation);
1502         assertEquals(NUM_PASSPOINT_PROVIDER_INSTALL_SUCCESS,
1503                 mDecodedProto.numPasspointProviderInstallSuccess);
1504         assertEquals(NUM_PASSPOINT_PROVIDER_UNINSTALLATION,
1505                 mDecodedProto.numPasspointProviderUninstallation);
1506         assertEquals(NUM_PASSPOINT_PROVIDER_UNINSTALL_SUCCESS,
1507                 mDecodedProto.numPasspointProviderUninstallSuccess);
1508         assertEquals(NUM_PASSPOINT_PROVIDERS_SUCCESSFULLY_CONNECTED,
1509                 mDecodedProto.numPasspointProvidersSuccessfullyConnected);
1510         assertEquals(NUM_PASSPOINT_PROVIDERS_WITH_NO_ROOT_CA,
1511                 mDecodedProto.numPasspointProviderWithNoRootCa);
1512         assertEquals(NUM_PASSPOINT_PROVIDERS_WITH_SELF_SIGNED_ROOT_CA,
1513                 mDecodedProto.numPasspointProviderWithSelfSignedRootCa);
1514         assertEquals(NUM_PASSPOINT_PROVIDERS_WITH_EXPIRATION_DATE,
1515                 mDecodedProto.numPasspointProviderWithSubscriptionExpiration);
1516         assertEquals(NUM_BSSID_SELECTION_DIFFERENT_BETWEEN_FRAMEWORK_FIRMWARE,
1517                 mDecodedProto.numBssidDifferentSelectionBetweenFrameworkAndFirmware);
1518 
1519         assertEquals(NUM_RADIO_MODE_CHANGE_TO_MCC, mDecodedProto.numRadioModeChangeToMcc);
1520         assertEquals(NUM_RADIO_MODE_CHANGE_TO_SCC, mDecodedProto.numRadioModeChangeToScc);
1521         assertEquals(NUM_RADIO_MODE_CHANGE_TO_SBS, mDecodedProto.numRadioModeChangeToSbs);
1522         assertEquals(NUM_RADIO_MODE_CHANGE_TO_DBS, mDecodedProto.numRadioModeChangeToDbs);
1523         assertEquals(NUM_SOFTAP_USER_BAND_PREFERENCE_UNSATISFIED,
1524                 mDecodedProto.numSoftApUserBandPreferenceUnsatisfied);
1525 
1526         PnoScanMetrics pno_metrics = mDecodedProto.pnoScanMetrics;
1527         assertNotNull(pno_metrics);
1528         assertEquals(NUM_PNO_SCAN_ATTEMPTS, pno_metrics.numPnoScanAttempts);
1529         assertEquals(NUM_PNO_SCAN_FAILED, pno_metrics.numPnoScanFailed);
1530         assertEquals(NUM_PNO_FOUND_NETWORK_EVENTS, pno_metrics.numPnoFoundNetworkEvents);
1531 
1532         for (ConnectToNetworkNotificationAndActionCount notificationCount
1533                 : mDecodedProto.connectToNetworkNotificationCount) {
1534             assertEquals(NUM_CONNECT_TO_NETWORK_NOTIFICATIONS[notificationCount.notification],
1535                     notificationCount.count);
1536             assertEquals(ConnectToNetworkNotificationAndActionCount.RECOMMENDER_OPEN,
1537                     notificationCount.recommender);
1538         }
1539         for (ConnectToNetworkNotificationAndActionCount notificationActionCount
1540                 : mDecodedProto.connectToNetworkNotificationActionCount) {
1541             assertEquals(NUM_CONNECT_TO_NETWORK_NOTIFICATION_ACTIONS
1542                             [notificationActionCount.notification]
1543                             [notificationActionCount.action],
1544                     notificationActionCount.count);
1545             assertEquals(ConnectToNetworkNotificationAndActionCount.RECOMMENDER_OPEN,
1546                     notificationActionCount.recommender);
1547         }
1548 
1549         assertEquals(SIZE_OPEN_NETWORK_RECOMMENDER_BLOCKLIST,
1550                 mDecodedProto.openNetworkRecommenderBlocklistSize);
1551         assertEquals(IS_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
1552                 mDecodedProto.isWifiNetworksAvailableNotificationOn);
1553         assertEquals(NUM_OPEN_NETWORK_RECOMMENDATION_UPDATES,
1554                 mDecodedProto.numOpenNetworkRecommendationUpdates);
1555         assertEquals(NUM_OPEN_NETWORK_CONNECT_MESSAGE_FAILED_TO_SEND,
1556                 mDecodedProto.numOpenNetworkConnectMessageFailedToSend);
1557 
1558         verifySoftApEventsStoredInProto();
1559 
1560         assertEquals(NUM_WATCHDOG_SUCCESS_DURATION_MS,
1561                 mDecodedProto.watchdogTriggerToConnectionSuccessDurationMs);
1562         assertEquals(IS_MAC_RANDOMIZATION_ON, mDecodedProto.isMacRandomizationOn);
1563         assertEquals(WIFI_POWER_METRICS_LOGGING_DURATION,
1564                 mDecodedProto.wifiRadioUsage.loggingDurationMs);
1565         assertEquals(WIFI_POWER_METRICS_SCAN_TIME,
1566                 mDecodedProto.wifiRadioUsage.scanTimeMs);
1567         assertEquals(WIFI_IS_UNUSABLE_EVENT_LOGGING_SETTING,
1568                 mDecodedProto.experimentValues.wifiIsUnusableLoggingEnabled);
1569         assertEquals(LINK_SPEED_COUNTS_LOGGING_SETTING,
1570                 mDecodedProto.experimentValues.linkSpeedCountsLoggingEnabled);
1571         assertEquals(DATA_STALL_MIN_TX_BAD_SETTING,
1572                 mDecodedProto.experimentValues.wifiDataStallMinTxBad);
1573         assertEquals(DATA_STALL_MIN_TX_SUCCESS_WITHOUT_RX_SETTING,
1574                 mDecodedProto.experimentValues.wifiDataStallMinTxSuccessWithoutRx);
1575         assertEquals(NUM_ONESHOT_SCAN_REQUESTS_WITH_DFS_CHANNELS,
1576                 mDecodedProto.numOneshotHasDfsChannelScans);
1577         assertEquals(NUM_ADD_OR_UPDATE_NETWORK_CALLS, mDecodedProto.numAddOrUpdateNetworkCalls);
1578         assertEquals(NUM_ENABLE_NETWORK_CALLS, mDecodedProto.numEnableNetworkCalls);
1579         assertEquals(NUM_IP_RENEWAL_FAILURE, mDecodedProto.numIpRenewalFailure);
1580         assertEquals(NUM_NETWORK_ABNORMAL_ASSOC_REJECTION,
1581                 mDecodedProto.healthMonitorMetrics.failureStatsIncrease.cntAssocRejection);
1582         assertEquals(NUM_NETWORK_ABNORMAL_CONNECTION_FAILURE_DISCONNECTION,
1583                 mDecodedProto.healthMonitorMetrics.failureStatsDecrease
1584                         .cntDisconnectionNonlocalConnecting);
1585         assertEquals(0,
1586                 mDecodedProto.healthMonitorMetrics.failureStatsIncrease.cntAssocTimeout);
1587         assertEquals(NUM_NETWORK_SUFFICIENT_RECENT_STATS_ONLY,
1588                 mDecodedProto.healthMonitorMetrics.numNetworkSufficientRecentStatsOnly);
1589         assertEquals(NUM_NETWORK_SUFFICIENT_RECENT_PREV_STATS,
1590                 mDecodedProto.healthMonitorMetrics.numNetworkSufficientRecentPrevStats);
1591         assertEquals(NUM_BSSID_FILTERED_DUE_TO_MBO_ASSOC_DISALLOW_IND,
1592                 mDecodedProto.numBssidFilteredDueToMboAssocDisallowInd);
1593         assertEquals(NUM_STEERING_REQUEST,
1594                 mDecodedProto.numSteeringRequest);
1595         assertEquals(NUM_FORCE_SCAN_DUE_TO_STEERING_REQUEST,
1596                 mDecodedProto.numForceScanDueToSteeringRequest);
1597         assertEquals(NUM_MBO_CELLULAR_SWITCH_REQUEST,
1598                 mDecodedProto.numMboCellularSwitchRequest);
1599         assertEquals(NUM_STEERING_REQUEST_INCLUDING_MBO_ASSOC_RETRY_DELAY,
1600                 mDecodedProto.numSteeringRequestIncludingMboAssocRetryDelay);
1601         assertEquals(NUM_CONNECT_REQUEST_WITH_FILS_AKM,
1602                 mDecodedProto.numConnectRequestWithFilsAkm);
1603         assertEquals(NUM_L2_CONNECTION_THROUGH_FILS_AUTHENTICATION,
1604                 mDecodedProto.numL2ConnectionThroughFilsAuthentication);
1605         assertEquals(WIFI_MAINLINE_MODULE_VERSION, mDecodedProto.mainlineModuleVersion);
1606 
1607     }
1608 
1609     /**
1610      *  Assert deserialized metrics Scan Return Entry equals count
1611      */
assertScanReturnEntryEquals(int returnCode, int count)1612     public void assertScanReturnEntryEquals(int returnCode, int count) {
1613         for (int i = 0; i < mDecodedProto.scanReturnEntries.length; i++) {
1614             if (mDecodedProto.scanReturnEntries[i].scanReturnCode == returnCode) {
1615                 assertEquals(count, mDecodedProto.scanReturnEntries[i].scanResultsCount);
1616                 return;
1617             }
1618         }
1619         assertEquals(null, count);
1620     }
1621 
1622     /**
1623      *  Assert deserialized metrics SystemState entry equals count
1624      */
assertSystemStateEntryEquals(int state, boolean screenOn, int count)1625     public void assertSystemStateEntryEquals(int state, boolean screenOn, int count) {
1626         for (int i = 0; i < mDecodedProto.wifiSystemStateEntries.length; i++) {
1627             if (mDecodedProto.wifiSystemStateEntries[i].wifiState == state
1628                     && mDecodedProto.wifiSystemStateEntries[i].isScreenOn == screenOn) {
1629                 assertEquals(count, mDecodedProto.wifiSystemStateEntries[i].wifiStateCount);
1630                 return;
1631             }
1632         }
1633         assertEquals(null, count);
1634     }
1635 
1636     /**
1637      * Test the number of Passpoint provision with the failure code are collected correctly
1638      *
1639      * @throws Exception
1640      */
1641     @Test
testPasspointProvisionMetrics()1642     public void testPasspointProvisionMetrics() throws Exception {
1643         //Increment count for provisioning success.
1644         mWifiMetrics.incrementPasspointProvisionSuccess();
1645 
1646         // Increment count for provisioning unavailable
1647         mWifiMetrics.incrementPasspointProvisionFailure(
1648                 ProvisioningCallback.OSU_FAILURE_PROVISIONING_NOT_AVAILABLE);
1649         mWifiMetrics.incrementPasspointProvisionFailure(
1650                 ProvisioningCallback.OSU_FAILURE_PROVISIONING_NOT_AVAILABLE);
1651 
1652         // Increment count for server connection failure
1653         mWifiMetrics.incrementPasspointProvisionFailure(
1654                 ProvisioningCallback.OSU_FAILURE_AP_CONNECTION);
1655 
1656         // Dump proto and deserialize
1657         dumpProtoAndDeserialize();
1658 
1659         assertEquals(mDecodedProto.passpointProvisionStats.numProvisionSuccess, 1);
1660         assertEquals(mDecodedProto.passpointProvisionStats.provisionFailureCount.length, 2);
1661         assertEquals(mDecodedProto.passpointProvisionStats.provisionFailureCount[0].failureCode,
1662                 PasspointProvisionStats.OSU_FAILURE_AP_CONNECTION);
1663         assertEquals(mDecodedProto.passpointProvisionStats.provisionFailureCount[0].count, 1);
1664         assertEquals(mDecodedProto.passpointProvisionStats.provisionFailureCount[1].failureCode,
1665                 PasspointProvisionStats.OSU_FAILURE_PROVISIONING_NOT_AVAILABLE);
1666         assertEquals(mDecodedProto.passpointProvisionStats.provisionFailureCount[1].count, 2);
1667     }
1668 
1669     /**
1670      * Combination of all other WifiMetrics unit tests, an internal-integration test, or functional
1671      * test
1672      */
1673     @Test
setMetricsSerializeDeserializeAssertMetricsSame()1674     public void setMetricsSerializeDeserializeAssertMetricsSame() throws Exception {
1675         setAndIncrementMetrics();
1676         startAndEndConnectionEventSucceeds();
1677         dumpProtoAndDeserialize();
1678         assertDeserializedMetricsCorrect();
1679         assertEquals("mDecodedProto.connectionEvent.length",
1680                 2, mDecodedProto.connectionEvent.length);
1681         //<TODO> test individual connectionEvents for correctness,
1682         // check scanReturnEntries & wifiSystemStateEntries counts and individual elements
1683         // pending their implementation</TODO>
1684     }
1685 
1686     /**
1687      * Test that score breach events are properly generated
1688      */
1689     @Test
testScoreBeachEvents()1690     public void testScoreBeachEvents() throws Exception {
1691         int upper = WifiMetrics.LOW_WIFI_SCORE + 7;
1692         int mid = WifiMetrics.LOW_WIFI_SCORE;
1693         int lower = WifiMetrics.LOW_WIFI_SCORE - 8;
1694         mWifiMetrics.setWifiState(TEST_IFACE_NAME, WifiMetricsProto.WifiLog.WIFI_ASSOCIATED);
1695         for (int score = upper; score >= mid; score--) {
1696             mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, score);
1697         }
1698         mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, mid + 1);
1699         mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, lower); // First breach
1700         for (int score = lower; score <= mid; score++) {
1701             mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, score);
1702         }
1703         mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, mid - 1);
1704         mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, upper); // Second breach
1705 
1706         dumpProtoAndDeserialize();
1707 
1708         assertEquals(2, mDecodedProto.staEventList.length);
1709         assertEquals(StaEvent.TYPE_SCORE_BREACH, mDecodedProto.staEventList[0].type);
1710         assertEquals(TEST_IFACE_NAME, mDecodedProto.staEventList[0].interfaceName);
1711         assertEquals(lower, mDecodedProto.staEventList[0].lastScore);
1712         assertEquals(StaEvent.TYPE_SCORE_BREACH, mDecodedProto.staEventList[1].type);
1713         assertEquals(TEST_IFACE_NAME, mDecodedProto.staEventList[1].interfaceName);
1714         assertEquals(upper, mDecodedProto.staEventList[1].lastScore);
1715     }
1716 
1717     /**
1718      * Test that Wifi usability score breach events are properly generated
1719      */
1720     @Test
testWifiUsabilityScoreBreachEvents()1721     public void testWifiUsabilityScoreBreachEvents() throws Exception {
1722         int upper = WifiMetrics.LOW_WIFI_USABILITY_SCORE + 7;
1723         int mid = WifiMetrics.LOW_WIFI_USABILITY_SCORE;
1724         int lower = WifiMetrics.LOW_WIFI_USABILITY_SCORE - 8;
1725         mWifiMetrics.setWifiState(TEST_IFACE_NAME, WifiMetricsProto.WifiLog.WIFI_ASSOCIATED);
1726         for (int score = upper; score >= mid; score--) {
1727             mWifiMetrics.incrementWifiUsabilityScoreCount(TEST_IFACE_NAME, 1, score, 15);
1728         }
1729         mWifiMetrics.incrementWifiUsabilityScoreCount(TEST_IFACE_NAME, 1, mid + 1, 15);
1730         // First breach
1731         mWifiMetrics.incrementWifiUsabilityScoreCount(TEST_IFACE_NAME, 1, lower, 15);
1732         for (int score = lower; score <= mid; score++) {
1733             mWifiMetrics.incrementWifiUsabilityScoreCount(TEST_IFACE_NAME, 1, score, 15);
1734         }
1735         mWifiMetrics.incrementWifiUsabilityScoreCount(TEST_IFACE_NAME, 1, mid - 1, 15);
1736         // Second breach
1737         mWifiMetrics.incrementWifiUsabilityScoreCount(TEST_IFACE_NAME, 1, upper, 15);
1738 
1739         dumpProtoAndDeserialize();
1740 
1741         assertEquals(2, mDecodedProto.staEventList.length);
1742         assertEquals(StaEvent.TYPE_WIFI_USABILITY_SCORE_BREACH, mDecodedProto.staEventList[0].type);
1743         assertEquals(lower, mDecodedProto.staEventList[0].lastWifiUsabilityScore);
1744         assertEquals(StaEvent.TYPE_WIFI_USABILITY_SCORE_BREACH, mDecodedProto.staEventList[1].type);
1745         assertEquals(upper, mDecodedProto.staEventList[1].lastWifiUsabilityScore);
1746     }
1747 
1748     /**
1749      * Test that WifiMetrics is correctly getting data from ScanDetail and WifiConfiguration
1750      */
1751     @Test
testScanDetailAndWifiConfigurationUsage()1752     public void testScanDetailAndWifiConfigurationUsage() throws Exception {
1753         setupNetworkAndVerify();
1754     }
1755 
1756     /**
1757      * Test that WifiMetrics is correctly getting data from ScanDetail and WifiConfiguration for
1758      * Passpoint use cases.
1759      */
1760     @Test
testScanDetailAndWifiConfigurationUsageForPasspoint()1761     public void testScanDetailAndWifiConfigurationUsageForPasspoint() throws Exception {
1762         setupNetworkAndVerify(true, false);
1763         setupNetworkAndVerify(true, true);
1764     }
1765 
1766     private static final String SSID = "red";
1767     private static final int CONFIG_DTIM = 3;
1768     private static final int NETWORK_DETAIL_WIFIMODE = 5;
1769     private static final int NETWORK_DETAIL_DTIM = 7;
1770     private static final int SCAN_RESULT_LEVEL = -30;
1771 
setupNetworkAndVerify()1772     private void setupNetworkAndVerify() throws Exception {
1773         setupNetworkAndVerify(false, false);
1774     }
1775 
setupNetworkAndVerify(boolean isPasspoint, boolean isPasspointHomeProvider)1776     private void setupNetworkAndVerify(boolean isPasspoint, boolean isPasspointHomeProvider)
1777             throws Exception {
1778         //Setup mock configs and scan details
1779         NetworkDetail networkDetail = mock(NetworkDetail.class);
1780         when(networkDetail.getWifiMode()).thenReturn(NETWORK_DETAIL_WIFIMODE);
1781         when(networkDetail.getSSID()).thenReturn(SSID);
1782         when(networkDetail.getDtimInterval()).thenReturn(NETWORK_DETAIL_DTIM);
1783         ScanResult scanResult = mock(ScanResult.class);
1784         scanResult.level = SCAN_RESULT_LEVEL;
1785         scanResult.capabilities = "EAP/SHA1";
1786         WifiConfiguration config = mock(WifiConfiguration.class);
1787         config.SSID = "\"" + SSID + "\"";
1788         config.dtimInterval = CONFIG_DTIM;
1789         config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO;
1790         config.allowedKeyManagement = new BitSet();
1791         config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
1792         config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
1793         config.enterpriseConfig = new WifiEnterpriseConfig();
1794         config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
1795         config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2);
1796         config.enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
1797         WifiConfiguration.NetworkSelectionStatus networkSelectionStat =
1798                 mock(WifiConfiguration.NetworkSelectionStatus.class);
1799         when(networkSelectionStat.getCandidate()).thenReturn(scanResult);
1800         when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStat);
1801         ScanDetail scanDetail = mock(ScanDetail.class);
1802         when(scanDetail.getNetworkDetail()).thenReturn(networkDetail);
1803         when(scanDetail.getScanResult()).thenReturn(scanResult);
1804         when(networkDetail.isMboSupported()).thenReturn(true);
1805         when(networkDetail.isOceSupported()).thenReturn(true);
1806 
1807         config.networkId = TEST_NETWORK_ID;
1808         mWifiMetrics.setNominatorForNetwork(TEST_NETWORK_ID,
1809                 WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL);
1810 
1811         when(config.isPasspoint()).thenReturn(isPasspoint);
1812         config.isHomeProviderNetwork = isPasspointHomeProvider;
1813 
1814         //Create a connection event using only the config
1815         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
1816                 "Red", WifiMetricsProto.ConnectionEvent.ROAM_NONE);
1817         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
1818                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
1819                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
1820                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
1821 
1822         //Change configuration to open without randomization
1823         config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
1824         scanResult.capabilities = "";
1825 
1826         //Create a connection event using the config and a scan detail
1827         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
1828                 "Green", WifiMetricsProto.ConnectionEvent.ROAM_NONE);
1829         mWifiMetrics.setConnectionScanDetail(TEST_IFACE_NAME, scanDetail);
1830         mWifiMetrics.logBugReport();
1831         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
1832                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
1833                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
1834                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
1835 
1836         //Dump proto from mWifiMetrics and deserialize it to mDecodedProto
1837         dumpProtoAndDeserialize();
1838 
1839         //Check that the correct values are being flowed through
1840         assertEquals(2, mDecodedProto.connectionEvent.length);
1841         assertEquals(CONFIG_DTIM, mDecodedProto.connectionEvent[0].routerFingerprint.dtim);
1842         assertEquals(WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE,
1843                 mDecodedProto.connectionEvent[0].routerFingerprint.authentication);
1844         assertEquals(WifiMetricsProto.RouterFingerPrint.TYPE_EAP_TTLS,
1845                 mDecodedProto.connectionEvent[0].routerFingerprint.eapMethod);
1846         assertEquals(WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_MSCHAPV2,
1847                 mDecodedProto.connectionEvent[0].routerFingerprint.authPhase2Method);
1848         assertEquals(WifiMetricsProto.RouterFingerPrint.TYPE_OCSP_REQUIRE_CERT_STATUS,
1849                 mDecodedProto.connectionEvent[0].routerFingerprint.ocspType);
1850         assertEquals(SCAN_RESULT_LEVEL, mDecodedProto.connectionEvent[0].signalStrength);
1851         assertEquals(NETWORK_DETAIL_DTIM, mDecodedProto.connectionEvent[1].routerFingerprint.dtim);
1852         assertEquals(WifiMetricsProto.RouterFingerPrint.AUTH_OPEN,
1853                 mDecodedProto.connectionEvent[1].routerFingerprint.authentication);
1854         assertEquals(WifiMetricsProto.RouterFingerPrint.TYPE_EAP_UNKNOWN,
1855                 mDecodedProto.connectionEvent[1].routerFingerprint.eapMethod);
1856         assertEquals(WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_NONE,
1857                 mDecodedProto.connectionEvent[1].routerFingerprint.authPhase2Method);
1858         assertEquals(WifiMetricsProto.RouterFingerPrint.TYPE_OCSP_NONE,
1859                 mDecodedProto.connectionEvent[1].routerFingerprint.ocspType);
1860         assertEquals(SCAN_RESULT_LEVEL, mDecodedProto.connectionEvent[1].signalStrength);
1861         assertEquals(NETWORK_DETAIL_WIFIMODE,
1862                 mDecodedProto.connectionEvent[1].routerFingerprint.routerTechnology);
1863         assertFalse(mDecodedProto.connectionEvent[0].automaticBugReportTaken);
1864         assertTrue(mDecodedProto.connectionEvent[1].automaticBugReportTaken);
1865         assertTrue(mDecodedProto.connectionEvent[0].useRandomizedMac);
1866         assertFalse(mDecodedProto.connectionEvent[1].useRandomizedMac);
1867         assertEquals(WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL,
1868                 mDecodedProto.connectionEvent[0].connectionNominator);
1869         assertEquals(1, mDecodedProto.numConnectToNetworkSupportingMbo);
1870         assertEquals(1, mDecodedProto.numConnectToNetworkSupportingOce);
1871         assertEquals(isPasspoint, mDecodedProto.connectionEvent[0].routerFingerprint.passpoint);
1872         assertEquals(isPasspointHomeProvider,
1873                 mDecodedProto.connectionEvent[0].routerFingerprint.isPasspointHomeProvider);
1874     }
1875 
1876     /**
1877      * Tests that the mapping from networkId to nominatorId is not cleared.
1878      */
1879     @Test
testNetworkToNominatorNotCleared()1880     public void testNetworkToNominatorNotCleared() throws Exception {
1881         //Setup mock configs and scan details
1882         NetworkDetail networkDetail = mock(NetworkDetail.class);
1883         when(networkDetail.getWifiMode()).thenReturn(NETWORK_DETAIL_WIFIMODE);
1884         when(networkDetail.getSSID()).thenReturn(SSID);
1885         when(networkDetail.getDtimInterval()).thenReturn(NETWORK_DETAIL_DTIM);
1886         ScanResult scanResult = mock(ScanResult.class);
1887         scanResult.level = SCAN_RESULT_LEVEL;
1888         WifiConfiguration config = mock(WifiConfiguration.class);
1889         config.SSID = "\"" + SSID + "\"";
1890         config.dtimInterval = CONFIG_DTIM;
1891         config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_AUTO;
1892         config.allowedKeyManagement = new BitSet();
1893         WifiConfiguration.NetworkSelectionStatus networkSelectionStat =
1894                 mock(WifiConfiguration.NetworkSelectionStatus.class);
1895         when(networkSelectionStat.getCandidate()).thenReturn(scanResult);
1896         when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStat);
1897         ScanDetail scanDetail = mock(ScanDetail.class);
1898         when(scanDetail.getNetworkDetail()).thenReturn(networkDetail);
1899         when(scanDetail.getScanResult()).thenReturn(scanResult);
1900 
1901         config.networkId = TEST_NETWORK_ID;
1902         mWifiMetrics.setNominatorForNetwork(TEST_NETWORK_ID,
1903                 WifiMetricsProto.ConnectionEvent.NOMINATOR_CARRIER);
1904 
1905         // dump() calls clear() internally
1906         mWifiMetrics.dump(null, new PrintWriter(new StringWriter()),
1907                 new String[]{WifiMetrics.PROTO_DUMP_ARG});
1908 
1909         // Create a connection event using only the config
1910         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
1911                 "Red", WifiMetricsProto.ConnectionEvent.ROAM_NONE);
1912         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
1913                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
1914                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
1915                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
1916 
1917         dumpProtoAndDeserialize();
1918 
1919         assertEquals(WifiMetricsProto.ConnectionEvent.NOMINATOR_CARRIER,
1920                 mDecodedProto.connectionEvent[0].connectionNominator);
1921     }
1922 
1923     /**
1924      * Test that WifiMetrics is serializing/deserializing association time out events.
1925      */
1926     @Test
testMetricsAssociationTimedOut()1927     public void testMetricsAssociationTimedOut() throws Exception {
1928         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
1929                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE);
1930         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
1931                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
1932                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
1933                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
1934 
1935         //Dump proto and deserialize
1936         //This should clear all the metrics in mWifiMetrics,
1937         dumpProtoAndDeserialize();
1938         //Check there is only 1 connection events
1939         assertEquals(1, mDecodedProto.connectionEvent.length);
1940         assertEquals(WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
1941                 mDecodedProto.connectionEvent[0].level2FailureCode);
1942         assertEquals(WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN,
1943                 mDecodedProto.connectionEvent[0].level2FailureReason);
1944     }
1945 
1946     /**
1947      * Verify the logging of number of blocked BSSIDs in ConnectionEvent.
1948      */
1949     @Test
testMetricNumBssidInBlocklist()1950     public void testMetricNumBssidInBlocklist() throws Exception {
1951         WifiConfiguration config = mock(WifiConfiguration.class);
1952         config.SSID = "\"" + SSID + "\"";
1953         config.allowedKeyManagement = new BitSet();
1954         when(config.getNetworkSelectionStatus()).thenReturn(
1955                 mock(WifiConfiguration.NetworkSelectionStatus.class));
1956         when(mWifiBlocklistMonitor.updateAndGetNumBlockedBssidsForSsid(eq(config.SSID)))
1957                 .thenReturn(3);
1958         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
1959                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE);
1960         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
1961                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
1962                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
1963                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
1964         dumpProtoAndDeserialize();
1965 
1966         assertEquals(1, mDecodedProto.connectionEvent.length);
1967         assertEquals(3, mDecodedProto.connectionEvent[0].numBssidInBlocklist);
1968     }
1969 
1970     /**
1971      * Verify the ConnectionEvent is labeled with networkType open network correctly.
1972      */
1973     @Test
testConnectionNetworkTypeOpen()1974     public void testConnectionNetworkTypeOpen() throws Exception {
1975         WifiConfiguration config = mock(WifiConfiguration.class);
1976         config.SSID = "\"" + SSID + "\"";
1977         config.allowedKeyManagement = new BitSet();
1978         when(config.getNetworkSelectionStatus()).thenReturn(
1979                 mock(WifiConfiguration.NetworkSelectionStatus.class));
1980         when(config.isOpenNetwork()).thenReturn(true);
1981         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
1982                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE);
1983         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
1984                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
1985                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
1986                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
1987         dumpProtoAndDeserialize();
1988 
1989         assertEquals(1, mDecodedProto.connectionEvent.length);
1990         assertEquals(WifiMetricsProto.ConnectionEvent.TYPE_OPEN,
1991                 mDecodedProto.connectionEvent[0].networkType);
1992         assertFalse(mDecodedProto.connectionEvent[0].isOsuProvisioned);
1993     }
1994 
1995     @Test
testStart2ConnectionEventsOnDifferentIfaces_endOneAndDump_endOtherAndDump()1996     public void testStart2ConnectionEventsOnDifferentIfaces_endOneAndDump_endOtherAndDump()
1997             throws Exception {
1998         WifiConfiguration config1 = WifiConfigurationTestUtil.createPskNetwork();
1999         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config1, "RED",
2000                 WifiMetricsProto.ConnectionEvent.ROAM_DBDC);
2001         WifiConfiguration config2 = WifiConfigurationTestUtil.createOpenNetwork();
2002         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME2, config2, "BLUE",
2003                 WifiMetricsProto.ConnectionEvent.ROAM_USER_SELECTED);
2004 
2005         mWifiMetrics.setConnectionScanDetail(TEST_IFACE_NAME, mock(ScanDetail.class));
2006         mWifiMetrics.setConnectionPmkCache(TEST_IFACE_NAME, false);
2007         mWifiMetrics.setConnectionMaxSupportedLinkSpeedMbps(TEST_IFACE_NAME, 100, 50);
2008 
2009         mWifiMetrics.setConnectionScanDetail(TEST_IFACE_NAME2, mock(ScanDetail.class));
2010         mWifiMetrics.setConnectionPmkCache(TEST_IFACE_NAME2, true);
2011         mWifiMetrics.setConnectionMaxSupportedLinkSpeedMbps(TEST_IFACE_NAME2, 400, 200);
2012 
2013         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME2,
2014                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
2015                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2016                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_TIMEOUT, 5745);
2017 
2018         dumpProtoAndDeserialize();
2019 
2020         assertEquals(1, mDecodedProto.connectionEvent.length);
2021         WifiMetricsProto.ConnectionEvent connectionEvent = mDecodedProto.connectionEvent[0];
2022         assertEquals(TEST_IFACE_NAME2, connectionEvent.interfaceName);
2023         assertTrue(connectionEvent.routerFingerprint.pmkCacheEnabled);
2024         assertEquals(400, connectionEvent.routerFingerprint.maxSupportedTxLinkSpeedMbps);
2025         assertEquals(200, connectionEvent.routerFingerprint.maxSupportedRxLinkSpeedMbps);
2026         assertEquals(WifiMetricsProto.ConnectionEvent.ROAM_USER_SELECTED, connectionEvent.roamType);
2027         assertEquals(WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_TIMEOUT,
2028                 connectionEvent.level2FailureReason);
2029 
2030         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2031                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION,
2032                 WifiMetricsProto.ConnectionEvent.HLF_DHCP,
2033                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_WRONG_PSWD, 2412);
2034 
2035         dumpProtoAndDeserialize();
2036 
2037         assertEquals(1, mDecodedProto.connectionEvent.length);
2038         connectionEvent = mDecodedProto.connectionEvent[0];
2039         assertEquals(TEST_IFACE_NAME, connectionEvent.interfaceName);
2040         assertFalse(connectionEvent.routerFingerprint.pmkCacheEnabled);
2041         assertEquals(100, connectionEvent.routerFingerprint.maxSupportedTxLinkSpeedMbps);
2042         assertEquals(50, connectionEvent.routerFingerprint.maxSupportedRxLinkSpeedMbps);
2043         assertEquals(WifiMetricsProto.ConnectionEvent.ROAM_DBDC, connectionEvent.roamType);
2044         assertEquals(WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_WRONG_PSWD,
2045                 connectionEvent.level2FailureReason);
2046     }
2047 
2048     @Test
testStart2ConnectionEventsOnDifferentIfaces_end2AndDump()2049     public void testStart2ConnectionEventsOnDifferentIfaces_end2AndDump() throws Exception {
2050         WifiConfiguration config1 = WifiConfigurationTestUtil.createPskNetwork();
2051         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config1, "RED",
2052                 WifiMetricsProto.ConnectionEvent.ROAM_DBDC);
2053         WifiConfiguration config2 = WifiConfigurationTestUtil.createOpenNetwork();
2054         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME2, config2, "BLUE",
2055                 WifiMetricsProto.ConnectionEvent.ROAM_USER_SELECTED);
2056 
2057         mWifiMetrics.setConnectionScanDetail(TEST_IFACE_NAME, mock(ScanDetail.class));
2058         mWifiMetrics.setConnectionPmkCache(TEST_IFACE_NAME, false);
2059         mWifiMetrics.setConnectionMaxSupportedLinkSpeedMbps(TEST_IFACE_NAME, 100, 50);
2060 
2061         mWifiMetrics.setConnectionScanDetail(TEST_IFACE_NAME2, mock(ScanDetail.class));
2062         mWifiMetrics.setConnectionPmkCache(TEST_IFACE_NAME2, true);
2063         mWifiMetrics.setConnectionMaxSupportedLinkSpeedMbps(TEST_IFACE_NAME2, 400, 200);
2064 
2065         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2066                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION,
2067                 WifiMetricsProto.ConnectionEvent.HLF_DHCP,
2068                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_WRONG_PSWD, 2412);
2069 
2070         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME2,
2071                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
2072                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2073                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_TIMEOUT, 5745);
2074 
2075         dumpProtoAndDeserialize();
2076 
2077         assertEquals(2, mDecodedProto.connectionEvent.length);
2078 
2079         WifiMetricsProto.ConnectionEvent connectionEvent = mDecodedProto.connectionEvent[0];
2080         assertEquals(TEST_IFACE_NAME, connectionEvent.interfaceName);
2081         assertFalse(connectionEvent.routerFingerprint.pmkCacheEnabled);
2082         assertEquals(100, connectionEvent.routerFingerprint.maxSupportedTxLinkSpeedMbps);
2083         assertEquals(50, connectionEvent.routerFingerprint.maxSupportedRxLinkSpeedMbps);
2084         assertEquals(WifiMetricsProto.ConnectionEvent.ROAM_DBDC, connectionEvent.roamType);
2085         assertEquals(WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_WRONG_PSWD,
2086                 connectionEvent.level2FailureReason);
2087 
2088         connectionEvent = mDecodedProto.connectionEvent[1];
2089         assertEquals(TEST_IFACE_NAME2, connectionEvent.interfaceName);
2090         assertTrue(connectionEvent.routerFingerprint.pmkCacheEnabled);
2091         assertEquals(400, connectionEvent.routerFingerprint.maxSupportedTxLinkSpeedMbps);
2092         assertEquals(200, connectionEvent.routerFingerprint.maxSupportedRxLinkSpeedMbps);
2093         assertEquals(WifiMetricsProto.ConnectionEvent.ROAM_USER_SELECTED, connectionEvent.roamType);
2094         assertEquals(WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_TIMEOUT,
2095                 connectionEvent.level2FailureReason);
2096     }
2097 
2098     @Test
testStartAndEnd2ConnectionEventsOnDifferentIfacesAndDump()2099     public void testStartAndEnd2ConnectionEventsOnDifferentIfacesAndDump() throws Exception {
2100         WifiConfiguration config1 = WifiConfigurationTestUtil.createPskNetwork();
2101         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config1, "RED",
2102                 WifiMetricsProto.ConnectionEvent.ROAM_DBDC);
2103         mWifiMetrics.setConnectionScanDetail(TEST_IFACE_NAME, mock(ScanDetail.class));
2104         mWifiMetrics.setConnectionPmkCache(TEST_IFACE_NAME, false);
2105         mWifiMetrics.setConnectionMaxSupportedLinkSpeedMbps(TEST_IFACE_NAME, 100, 50);
2106         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2107                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION,
2108                 WifiMetricsProto.ConnectionEvent.HLF_DHCP,
2109                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_WRONG_PSWD, 2412);
2110 
2111         WifiConfiguration config2 = WifiConfigurationTestUtil.createOpenNetwork();
2112         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME2, config2, "BLUE",
2113                 WifiMetricsProto.ConnectionEvent.ROAM_USER_SELECTED);
2114         mWifiMetrics.setConnectionScanDetail(TEST_IFACE_NAME2, mock(ScanDetail.class));
2115         mWifiMetrics.setConnectionPmkCache(TEST_IFACE_NAME2, true);
2116         mWifiMetrics.setConnectionMaxSupportedLinkSpeedMbps(TEST_IFACE_NAME2, 400, 200);
2117         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME2,
2118                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
2119                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2120                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_TIMEOUT, 5745);
2121 
2122         dumpProtoAndDeserialize();
2123 
2124         assertEquals(2, mDecodedProto.connectionEvent.length);
2125 
2126         WifiMetricsProto.ConnectionEvent connectionEvent = mDecodedProto.connectionEvent[0];
2127         assertEquals(TEST_IFACE_NAME, connectionEvent.interfaceName);
2128         assertFalse(connectionEvent.routerFingerprint.pmkCacheEnabled);
2129         assertEquals(100, connectionEvent.routerFingerprint.maxSupportedTxLinkSpeedMbps);
2130         assertEquals(50, connectionEvent.routerFingerprint.maxSupportedRxLinkSpeedMbps);
2131         assertEquals(WifiMetricsProto.ConnectionEvent.ROAM_DBDC, connectionEvent.roamType);
2132         assertEquals(WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_WRONG_PSWD,
2133                 connectionEvent.level2FailureReason);
2134 
2135         connectionEvent = mDecodedProto.connectionEvent[1];
2136         assertEquals(TEST_IFACE_NAME2, connectionEvent.interfaceName);
2137         assertTrue(connectionEvent.routerFingerprint.pmkCacheEnabled);
2138         assertEquals(400, connectionEvent.routerFingerprint.maxSupportedTxLinkSpeedMbps);
2139         assertEquals(200, connectionEvent.routerFingerprint.maxSupportedRxLinkSpeedMbps);
2140         assertEquals(WifiMetricsProto.ConnectionEvent.ROAM_USER_SELECTED, connectionEvent.roamType);
2141         assertEquals(WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_TIMEOUT,
2142                 connectionEvent.level2FailureReason);
2143     }
2144 
2145     @Test
testNonExistentConnectionEventIface_doesntCrash()2146     public void testNonExistentConnectionEventIface_doesntCrash() throws Exception {
2147         mWifiMetrics.setConnectionScanDetail("nonexistentIface", mock(ScanDetail.class));
2148         mWifiMetrics.setConnectionPmkCache("nonexistentIface", false);
2149         mWifiMetrics.setConnectionMaxSupportedLinkSpeedMbps("nonexistentIface", 100, 50);
2150         mWifiMetrics.endConnectionEvent("nonexistentIface",
2151                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION,
2152                 WifiMetricsProto.ConnectionEvent.HLF_DHCP,
2153                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_WRONG_PSWD, 2412);
2154     }
2155 
2156     /**
2157      * Verify the ConnectionEvent is labeled with networkType Passpoint correctly.
2158      */
2159     @Test
testConnectionNetworkTypePasspoint()2160     public void testConnectionNetworkTypePasspoint() throws Exception {
2161         WifiConfiguration config = WifiConfigurationTestUtil.createPasspointNetwork();
2162         config.carrierMerged = true;
2163         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
2164                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE);
2165         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2166                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
2167                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2168                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
2169         dumpProtoAndDeserialize();
2170 
2171         assertEquals(1, mDecodedProto.connectionEvent.length);
2172         assertEquals(WifiMetricsProto.ConnectionEvent.TYPE_PASSPOINT,
2173                 mDecodedProto.connectionEvent[0].networkType);
2174         assertFalse(mDecodedProto.connectionEvent[0].isOsuProvisioned);
2175         assertTrue(mDecodedProto.connectionEvent[0].isCarrierMerged);
2176     }
2177 
2178     /**
2179      * Verify the ConnectionEvent is created with correct creatorUid.
2180      */
2181     @Test
testConnectionCreatorUid()2182     public void testConnectionCreatorUid() throws Exception {
2183         WifiConfiguration config = mock(WifiConfiguration.class);
2184         config.SSID = "\"" + SSID + "\"";
2185         config.allowedKeyManagement = new BitSet();
2186         when(config.getNetworkSelectionStatus()).thenReturn(
2187                 mock(WifiConfiguration.NetworkSelectionStatus.class));
2188 
2189         // First network is created by the user
2190         config.fromWifiNetworkSuggestion = false;
2191         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
2192                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE);
2193         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2194                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
2195                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2196                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
2197 
2198         // Second network is created by a carrier app
2199         config.fromWifiNetworkSuggestion = true;
2200         config.carrierId = 123;
2201         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
2202                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE);
2203         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2204                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
2205                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2206                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
2207 
2208         // Third network is created by an unknown app
2209         config.fromWifiNetworkSuggestion = true;
2210         config.carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
2211         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
2212                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE);
2213         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2214                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
2215                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2216                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
2217 
2218         dumpProtoAndDeserialize();
2219 
2220         assertEquals(3, mDecodedProto.connectionEvent.length);
2221         assertEquals(WifiMetricsProto.ConnectionEvent.CREATOR_USER,
2222                 mDecodedProto.connectionEvent[0].networkCreator);
2223         assertEquals(WifiMetricsProto.ConnectionEvent.CREATOR_CARRIER,
2224                 mDecodedProto.connectionEvent[1].networkCreator);
2225         assertEquals(WifiMetricsProto.ConnectionEvent.CREATOR_UNKNOWN,
2226                 mDecodedProto.connectionEvent[2].networkCreator);
2227     }
2228 
2229     /**
2230      * Test that WifiMetrics is serializing/deserializing authentication failure events.
2231      */
2232     @Test
testMetricsAuthenticationFailureReason()2233     public void testMetricsAuthenticationFailureReason() throws Exception {
2234         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
2235                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE);
2236         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2237                 WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
2238                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2239                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_WRONG_PSWD, 0);
2240 
2241         //Dump proto and deserialize
2242         //This should clear all the metrics in mWifiMetrics,
2243         dumpProtoAndDeserialize();
2244         //Check there is only 1 connection events
2245         assertEquals(1, mDecodedProto.connectionEvent.length);
2246         assertEquals(WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
2247                 mDecodedProto.connectionEvent[0].level2FailureCode);
2248         //Check the authentication failure reason
2249         assertEquals(WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_WRONG_PSWD,
2250                 mDecodedProto.connectionEvent[0].level2FailureReason);
2251     }
2252 
2253     /**
2254      * Test the logging of BssidBlocklistStats.
2255      */
2256     @Test
testBssidBlocklistMetrics()2257     public void testBssidBlocklistMetrics() throws Exception {
2258         for (int i = 0; i < 3; i++) {
2259             mWifiMetrics.incrementNetworkSelectionFilteredBssidCount(i);
2260             mWifiMetrics.incrementBssidBlocklistCount(
2261                     WifiBlocklistMonitor.REASON_ASSOCIATION_TIMEOUT);
2262             mWifiMetrics.incrementWificonfigurationBlocklistCount(
2263                     NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION);
2264         }
2265         mWifiMetrics.incrementNetworkSelectionFilteredBssidCount(2);
2266         mWifiMetrics.incrementBssidBlocklistCount(
2267                 WifiBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE);
2268         mWifiMetrics.incrementWificonfigurationBlocklistCount(
2269                 NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY);
2270         mResources.setBoolean(R.bool.config_wifiHighMovementNetworkSelectionOptimizationEnabled,
2271                 true);
2272         mWifiMetrics.incrementNumHighMovementConnectionStarted();
2273         mWifiMetrics.incrementNumHighMovementConnectionSkipped();
2274         mWifiMetrics.incrementNumHighMovementConnectionSkipped();
2275         dumpProtoAndDeserialize();
2276 
2277         Int32Count[] expectedFilteredBssidHistogram = {
2278                 buildInt32Count(0, 1),
2279                 buildInt32Count(1, 1),
2280                 buildInt32Count(2, 2),
2281         };
2282         Int32Count[] expectedBssidBlocklistPerReasonHistogram = {
2283                 buildInt32Count(WifiBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE, 1),
2284                 buildInt32Count(WifiBlocklistMonitor.REASON_ASSOCIATION_TIMEOUT, 3),
2285         };
2286         Int32Count[] expectedWificonfigBlocklistPerReasonHistogram = {
2287                 buildInt32Count(NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION, 3),
2288                 buildInt32Count(NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY, 1),
2289         };
2290         assertKeyCountsEqual(expectedFilteredBssidHistogram,
2291                 mDecodedProto.bssidBlocklistStats.networkSelectionFilteredBssidCount);
2292         assertKeyCountsEqual(expectedBssidBlocklistPerReasonHistogram,
2293                 mDecodedProto.bssidBlocklistStats.bssidBlocklistPerReasonCount);
2294         assertKeyCountsEqual(expectedWificonfigBlocklistPerReasonHistogram,
2295                 mDecodedProto.bssidBlocklistStats.wifiConfigBlocklistPerReasonCount);
2296         assertEquals(true, mDecodedProto.bssidBlocklistStats
2297                 .highMovementMultipleScansFeatureEnabled);
2298         assertEquals(1, mDecodedProto.bssidBlocklistStats.numHighMovementConnectionStarted);
2299         assertEquals(2, mDecodedProto.bssidBlocklistStats.numHighMovementConnectionSkipped);
2300     }
2301 
2302     /**
2303      * Test that WifiMetrics is being cleared after dumping via proto
2304      */
2305     @Test
testMetricsClearedAfterProtoRequested()2306     public void testMetricsClearedAfterProtoRequested() throws Exception {
2307         // Create 3 ConnectionEvents
2308         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
2309                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
2310         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2311                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
2312                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2313                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
2314         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
2315                 "YELLOW", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
2316         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2317                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
2318                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2319                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
2320         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
2321                 "GREEN", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
2322         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2323                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
2324                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2325                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
2326         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
2327                 "ORANGE", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
2328         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2329                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
2330                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2331                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
2332 
2333         //Dump proto and deserialize
2334         //This should clear all the metrics in mWifiMetrics,
2335         dumpProtoAndDeserialize();
2336         //Check there are 4 connection events
2337         assertEquals(4, mDecodedProto.connectionEvent.length);
2338         assertEquals(0, mDecodedProto.rssiPollRssiCount.length);
2339         assertEquals(0, mDecodedProto.alertReasonCount.length);
2340 
2341         // Create 2 ConnectionEvents
2342         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
2343                 "BLUE", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
2344         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2345                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
2346                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2347                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
2348         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
2349                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
2350         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2351                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
2352                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2353                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
2354 
2355         //Dump proto and deserialize
2356         dumpProtoAndDeserialize();
2357         //Check there are only 2 connection events
2358         assertEquals(2, mDecodedProto.connectionEvent.length);
2359     }
2360 
2361     /**
2362      * Test logging to statsd when a connection event finishes.
2363      */
2364     @Test
testLogWifiConnectionResultStatsd()2365     public void testLogWifiConnectionResultStatsd() throws Exception {
2366         // Start and end Connection event
2367         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
2368                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
2369         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2370                 WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
2371                 WifiMetricsProto.ConnectionEvent.HLF_DHCP,
2372                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, TEST_CANDIDATE_FREQ);
2373 
2374         ExtendedMockito.verify(() -> WifiStatsLog.write(
2375                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED, false,
2376                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__FAILURE_CODE__FAILURE_AUTHENTICATION_GENERAL,
2377                 -80, 0,
2378                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__BAND__BAND_2G,
2379                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__AUTH_TYPE__AUTH_TYPE_WPA2_PSK,
2380                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__AUTOCONNECT_BOOT,
2381                 true,
2382                 0));
2383     }
2384 
2385     /**
2386      * Test that current ongoing ConnectionEvent is not cleared and logged
2387      * when proto is dumped
2388      */
2389     @Test
testCurrentConnectionEventNotClearedAfterProtoRequested()2390     public void testCurrentConnectionEventNotClearedAfterProtoRequested() throws Exception {
2391         // Create 2 complete ConnectionEvents and 1 ongoing un-ended ConnectionEvent
2392         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
2393                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
2394         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2395                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
2396                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2397                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
2398         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
2399                 "YELLOW", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
2400         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2401                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
2402                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2403                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
2404         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, null,
2405                 "GREEN", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
2406 
2407         // Dump proto and deserialize
2408         // This should clear the metrics in mWifiMetrics,
2409         dumpProtoAndDeserialize();
2410         assertEquals(2, mDecodedProto.connectionEvent.length);
2411 
2412         // End the ongoing ConnectionEvent
2413         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
2414                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
2415                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
2416                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
2417 
2418         dumpProtoAndDeserialize();
2419         assertEquals(1, mDecodedProto.connectionEvent.length);
2420     }
2421 
2422     /**
2423      * Tests that after setting metrics values they can be serialized and deserialized with the
2424      *   $ adb shell dumpsys wifi wifiMetricsProto clean
2425      */
2426     @Test
testClearMetricsDump()2427     public void testClearMetricsDump() throws Exception {
2428         setAndIncrementMetrics();
2429         startAndEndConnectionEventSucceeds();
2430         cleanDumpProtoAndDeserialize();
2431         assertDeserializedMetricsCorrect();
2432         assertEquals("mDecodedProto.connectionEvent.length",
2433                 2, mDecodedProto.connectionEvent.length);
2434     }
2435 
2436     private static final int NUM_REPEATED_DELTAS = 7;
2437     private static final int REPEATED_DELTA = 0;
2438     private static final int SINGLE_GOOD_DELTA = 1;
2439     private static final int SINGLE_TIMEOUT_DELTA = 2;
2440     private static final int NUM_REPEATED_BOUND_DELTAS = 2;
2441     private static final int MAX_DELTA_LEVEL = 127;
2442     private static final int MIN_DELTA_LEVEL = -127;
2443     private static final int ARBITRARY_DELTA_LEVEL = 20;
2444 
2445     /**
2446      * Sunny day RSSI delta logging scenario.
2447      * Logs one rssi delta value multiple times
2448      * Logs a different delta value a single time
2449      */
2450     @Test
testRssiDeltasSuccessfulLogging()2451     public void testRssiDeltasSuccessfulLogging() throws Exception {
2452         // Generate some repeated deltas
2453         for (int i = 0; i < NUM_REPEATED_DELTAS; i++) {
2454             generateRssiDelta(MIN_RSSI_LEVEL, REPEATED_DELTA,
2455                     WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
2456         }
2457         // Generate a single delta
2458         generateRssiDelta(MIN_RSSI_LEVEL, SINGLE_GOOD_DELTA,
2459                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
2460         dumpProtoAndDeserialize();
2461         assertEquals(2, mDecodedProto.rssiPollDeltaCount.length);
2462         // Check the repeated deltas
2463         assertEquals(NUM_REPEATED_DELTAS, mDecodedProto.rssiPollDeltaCount[0].count);
2464         assertEquals(REPEATED_DELTA, mDecodedProto.rssiPollDeltaCount[0].rssi);
2465         // Check the single delta
2466         assertEquals(1, mDecodedProto.rssiPollDeltaCount[1].count);
2467         assertEquals(SINGLE_GOOD_DELTA, mDecodedProto.rssiPollDeltaCount[1].rssi);
2468     }
2469 
2470     /**
2471      * Tests that Rssi Delta events whose scanResult and Rssi Poll come too far apart, timeout,
2472      * and are not logged.
2473      */
2474     @Test
testRssiDeltasTimeout()2475     public void testRssiDeltasTimeout() throws Exception {
2476         // Create timed out rssi deltas
2477         generateRssiDelta(MIN_RSSI_LEVEL, REPEATED_DELTA,
2478                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS + 1);
2479         generateRssiDelta(MIN_RSSI_LEVEL, SINGLE_TIMEOUT_DELTA,
2480                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS + 1);
2481         dumpProtoAndDeserialize();
2482         assertEquals(0, mDecodedProto.rssiPollDeltaCount.length);
2483     }
2484 
2485     /**
2486      * Tests the exact inclusive boundaries of RSSI delta logging.
2487      */
2488     @Test
testRssiDeltaSuccessfulLoggingExactBounds()2489     public void testRssiDeltaSuccessfulLoggingExactBounds() throws Exception {
2490         generateRssiDelta(MIN_RSSI_LEVEL, MAX_DELTA_LEVEL,
2491                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
2492         generateRssiDelta(MAX_RSSI_LEVEL, MIN_DELTA_LEVEL,
2493                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
2494         dumpProtoAndDeserialize();
2495         assertEquals(2, mDecodedProto.rssiPollDeltaCount.length);
2496         assertEquals(MIN_DELTA_LEVEL, mDecodedProto.rssiPollDeltaCount[0].rssi);
2497         assertEquals(1, mDecodedProto.rssiPollDeltaCount[0].count);
2498         assertEquals(MAX_DELTA_LEVEL, mDecodedProto.rssiPollDeltaCount[1].rssi);
2499         assertEquals(1, mDecodedProto.rssiPollDeltaCount[1].count);
2500     }
2501 
2502     /**
2503      * Tests the exact exclusive boundaries of RSSI delta logging.
2504      * This test ensures that too much data is not generated.
2505      */
2506     @Test
testRssiDeltaOutOfBounds()2507     public void testRssiDeltaOutOfBounds() throws Exception {
2508         generateRssiDelta(MIN_RSSI_LEVEL, MAX_DELTA_LEVEL + 1,
2509                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
2510         generateRssiDelta(MAX_RSSI_LEVEL, MIN_DELTA_LEVEL - 1,
2511                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS);
2512         dumpProtoAndDeserialize();
2513         assertEquals(0, mDecodedProto.rssiPollDeltaCount.length);
2514     }
2515 
2516     /**
2517      * This test ensures no rssi Delta is logged after an unsuccessful ConnectionEvent
2518      */
2519     @Test
testUnsuccesfulConnectionEventRssiDeltaIsNotLogged()2520     public void testUnsuccesfulConnectionEventRssiDeltaIsNotLogged() throws Exception {
2521         generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL,
2522                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS,
2523                 false, // successfulConnectionEvent
2524                 true, // completeConnectionEvent
2525                 true, // useValidScanResult
2526                 true // dontDeserializeBeforePoll
2527         );
2528 
2529         dumpProtoAndDeserialize();
2530         assertEquals(0, mDecodedProto.rssiPollDeltaCount.length);
2531     }
2532 
2533     /**
2534      * This test ensures rssi Deltas can be logged during a ConnectionEvent
2535      */
2536     @Test
testIncompleteConnectionEventRssiDeltaIsLogged()2537     public void testIncompleteConnectionEventRssiDeltaIsLogged() throws Exception {
2538         generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL,
2539                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS,
2540                 true, // successfulConnectionEvent
2541                 false, // completeConnectionEvent
2542                 true, // useValidScanResult
2543                 true // dontDeserializeBeforePoll
2544         );
2545         dumpProtoAndDeserialize();
2546         assertEquals(1, mDecodedProto.rssiPollDeltaCount.length);
2547         assertEquals(ARBITRARY_DELTA_LEVEL, mDecodedProto.rssiPollDeltaCount[0].rssi);
2548         assertEquals(1, mDecodedProto.rssiPollDeltaCount[0].count);
2549     }
2550 
2551     /**
2552      * This test ensures that no delta is logged for a null ScanResult Candidate
2553      */
2554     @Test
testRssiDeltaNotLoggedForNullCandidateScanResult()2555     public void testRssiDeltaNotLoggedForNullCandidateScanResult() throws Exception {
2556         generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL,
2557                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS,
2558                 true, // successfulConnectionEvent
2559                 true, // completeConnectionEvent
2560                 false, // useValidScanResult
2561                 true // dontDeserializeBeforePoll
2562         );
2563         dumpProtoAndDeserialize();
2564         assertEquals(0, mDecodedProto.rssiPollDeltaCount.length);
2565     }
2566 
2567     /**
2568      * This test ensures that Rssi Deltas are not logged over a 'clear()' call (Metrics Serialized)
2569      */
2570     @Test
testMetricsSerializedDuringRssiDeltaEventLogsNothing()2571     public void testMetricsSerializedDuringRssiDeltaEventLogsNothing() throws Exception {
2572         generateRssiDelta(MIN_RSSI_LEVEL, ARBITRARY_DELTA_LEVEL,
2573                 WifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS,
2574                 true, // successfulConnectionEvent
2575                 true, // completeConnectionEvent
2576                 true, // useValidScanResult
2577                 false // dontDeserializeBeforePoll
2578         );
2579         dumpProtoAndDeserialize();
2580         assertEquals(0, mDecodedProto.rssiPollDeltaCount.length);
2581     }
2582 
2583     private static final int DEAUTH_REASON = 7;
2584     private static final int ASSOC_STATUS = 11;
2585     private static final boolean ASSOC_TIMEOUT = true;
2586     private static final boolean LOCAL_GEN = true;
2587     private static final int AUTH_FAILURE_REASON = WifiManager.ERROR_AUTH_FAILURE_WRONG_PSWD;
2588     private static final int NUM_TEST_STA_EVENTS = 19;
2589     private static final String   sSSID = "\"SomeTestSsid\"";
2590     private static final WifiSsid sWifiSsid = WifiSsid.createFromAsciiEncoded(sSSID);
2591     private static final String   sBSSID = "01:02:03:04:05:06";
2592 
2593     private final StateChangeResult mStateDisconnected =
2594             new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.DISCONNECTED);
2595     private final StateChangeResult mStateCompleted =
2596             new StateChangeResult(0, sWifiSsid, sBSSID, SupplicantState.COMPLETED);
2597     // Test bitmasks of supplicant state changes
2598     private final int mSupBm1 = WifiMetrics.supplicantStateToBit(mStateDisconnected.state);
2599     private final int mSupBm2 = WifiMetrics.supplicantStateToBit(mStateDisconnected.state)
2600             | WifiMetrics.supplicantStateToBit(mStateCompleted.state);
2601     // An invalid but interesting wifiConfiguration that exercises the StaEvent.ConfigInfo encoding
2602     private final WifiConfiguration mTestWifiConfig = createComplexWifiConfig();
2603     // <msg.what> <msg.arg1> <msg.arg2>
2604     private int[][] mTestStaMessageInts = {
2605         {WifiMonitor.ASSOCIATION_REJECTION_EVENT,   0,                   0},
2606         {WifiMonitor.AUTHENTICATION_FAILURE_EVENT,  AUTH_FAILURE_REASON, -1},
2607         {WifiMonitor.NETWORK_CONNECTION_EVENT,      0,                   0},
2608         {WifiMonitor.NETWORK_DISCONNECTION_EVENT,   0,                   0},
2609         {WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0,                   0},
2610         {WifiMonitor.ASSOCIATED_BSSID_EVENT,        0,                   0},
2611         {WifiMonitor.TARGET_BSSID_EVENT,            0,                   0},
2612         {WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0,                   0},
2613         {WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0,                   0}
2614     };
2615     private Object[] mTestStaMessageObjs = {
2616         new AssocRejectEventInfo(sSSID, sBSSID, ASSOC_STATUS, ASSOC_TIMEOUT),
2617         null,
2618         null,
2619         new DisconnectEventInfo(sSSID, sBSSID, DEAUTH_REASON, LOCAL_GEN),
2620         mStateDisconnected,
2621         null,
2622         null,
2623         mStateDisconnected,
2624         mStateCompleted
2625     };
2626     // Values used to generate the StaEvent log calls from ClientModeImpl
2627     // <StaEvent.Type>, <StaEvent.FrameworkDisconnectReason>, <1|0>(testWifiConfiguration, null)
2628     private int[][] mTestStaLogInts = {
2629         {StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL, 0,                          0},
2630         {StaEvent.TYPE_CMD_IP_CONFIGURATION_LOST,       0,                          0},
2631         {StaEvent.TYPE_CMD_IP_REACHABILITY_LOST,        0,                          0},
2632         {StaEvent.TYPE_CMD_START_CONNECT,               0,                          1},
2633         {StaEvent.TYPE_CMD_START_ROAM,                  0,                          1},
2634         {StaEvent.TYPE_CONNECT_NETWORK,                 0,                          1},
2635         {StaEvent.TYPE_NETWORK_AGENT_VALID_NETWORK,     0,                          0},
2636         {StaEvent.TYPE_FRAMEWORK_DISCONNECT,            StaEvent.DISCONNECT_API,    0},
2637         {StaEvent.TYPE_SCORE_BREACH,                    0,                          0},
2638         {StaEvent.TYPE_MAC_CHANGE,                      0,                          1},
2639         {StaEvent.TYPE_WIFI_ENABLED,                    0,                          0},
2640         {StaEvent.TYPE_WIFI_DISABLED,                   0,                          0},
2641         {StaEvent.TYPE_WIFI_USABILITY_SCORE_BREACH,     0,                          0}
2642     };
2643     // Values used to generate the StaEvent log calls from WifiMonitor
2644     // <type>, <reason>, <status>, <local_gen>,
2645     // <auth_fail_reason>, <assoc_timed_out> <supplicantStateChangeBitmask> <1|0>(has ConfigInfo)
2646     private int[][] mExpectedValues = {
2647         {StaEvent.TYPE_ASSOCIATION_REJECTION_EVENT,     -1,  ASSOC_STATUS,         0,
2648             /**/                               0, ASSOC_TIMEOUT ? 1 : 0,        0, 0},    /**/
2649         {StaEvent.TYPE_AUTHENTICATION_FAILURE_EVENT,    -1,            -1,         0,
2650             /**/StaEvent.AUTH_FAILURE_WRONG_PSWD,             0,        0, 0},    /**/
2651         {StaEvent.TYPE_NETWORK_CONNECTION_EVENT,        -1,            -1,         0,
2652             /**/                               0,             0,        0, 0},    /**/
2653         {StaEvent.TYPE_NETWORK_DISCONNECTION_EVENT, DEAUTH_REASON,     -1, LOCAL_GEN ? 1 : 0,
2654             /**/                               0,             0,        0, 0},    /**/
2655         {StaEvent.TYPE_CMD_ASSOCIATED_BSSID,            -1,            -1,         0,
2656             /**/                               0,             0,  mSupBm1, 0},    /**/
2657         {StaEvent.TYPE_CMD_TARGET_BSSID,                -1,            -1,         0,
2658             /**/                               0,             0,        0, 0},    /**/
2659         {StaEvent.TYPE_CMD_IP_CONFIGURATION_SUCCESSFUL, -1,            -1,         0,
2660             /**/                               0,             0,  mSupBm2, 0},    /**/
2661         {StaEvent.TYPE_CMD_IP_CONFIGURATION_LOST,       -1,            -1,         0,
2662             /**/                               0,             0,        0, 0},    /**/
2663         {StaEvent.TYPE_CMD_IP_REACHABILITY_LOST,        -1,            -1,         0,
2664             /**/                               0,             0,        0, 0},    /**/
2665         {StaEvent.TYPE_CMD_START_CONNECT,               -1,            -1,         0,
2666             /**/                               0,             0,        0, 1},    /**/
2667         {StaEvent.TYPE_CMD_START_ROAM,                  -1,            -1,         0,
2668             /**/                               0,             0,        0, 1},    /**/
2669         {StaEvent.TYPE_CONNECT_NETWORK,                 -1,            -1,         0,
2670             /**/                               0,             0,        0, 1},    /**/
2671         {StaEvent.TYPE_NETWORK_AGENT_VALID_NETWORK,     -1,            -1,         0,
2672             /**/                               0,             0,        0, 0},    /**/
2673         {StaEvent.TYPE_FRAMEWORK_DISCONNECT,            -1,            -1,         0,
2674             /**/                               0,             0,        0, 0},    /**/
2675         {StaEvent.TYPE_SCORE_BREACH,                    -1,            -1,         0,
2676             /**/                               0,             0,        0, 0},    /**/
2677         {StaEvent.TYPE_MAC_CHANGE,                      -1,            -1,         0,
2678             /**/                               0,             0,        0, 1},    /**/
2679         {StaEvent.TYPE_WIFI_ENABLED,                    -1,            -1,         0,
2680             /**/                               0,             0,        0, 0},    /**/
2681         {StaEvent.TYPE_WIFI_DISABLED,                   -1,            -1,         0,
2682             /**/                               0,             0,        0, 0},     /**/
2683         {StaEvent.TYPE_WIFI_USABILITY_SCORE_BREACH,     -1,            -1,         0,
2684             /**/                               0,             0,        0, 0}    /**/
2685     };
2686 
2687     /**
2688      * Generates events from all the rows in mTestStaMessageInts, and then mTestStaLogInts
2689      */
generateStaEvents(WifiMetrics wifiMetrics)2690     private void generateStaEvents(WifiMetrics wifiMetrics) {
2691         Handler handler = mHandlerCaptor.getValue();
2692         for (int i = 0; i < mTestStaMessageInts.length; i++) {
2693             int[] mia = mTestStaMessageInts[i];
2694             Message message = handler.obtainMessage(mia[0], mia[1], mia[2], mTestStaMessageObjs[i]);
2695             message.getData().putString(WifiMonitor.KEY_IFACE, TEST_IFACE_NAME);
2696             handler.sendMessage(message);
2697         }
2698         mTestLooper.dispatchAll();
2699         setScreenState(true);
2700         when(mWifiDataStall.isCellularDataAvailable()).thenReturn(true);
2701         wifiMetrics.setAdaptiveConnectivityState(true);
2702         for (int i = 0; i < mTestStaLogInts.length; i++) {
2703             int[] lia = mTestStaLogInts[i];
2704             wifiMetrics.logStaEvent(
2705                     TEST_IFACE_NAME, lia[0], lia[1], lia[2] == 1 ? mTestWifiConfig : null);
2706         }
2707     }
verifyDeserializedStaEvents(WifiMetricsProto.WifiLog wifiLog)2708     private void verifyDeserializedStaEvents(WifiMetricsProto.WifiLog wifiLog) {
2709         assertNotNull(mTestWifiConfig);
2710         assertEquals(NUM_TEST_STA_EVENTS, wifiLog.staEventList.length);
2711         int j = 0; // De-serialized event index
2712         for (int i = 0; i < mTestStaMessageInts.length; i++) {
2713             StaEvent event = wifiLog.staEventList[j];
2714             int[] mia = mTestStaMessageInts[i];
2715             int[] evs = mExpectedValues[j];
2716             if (mia[0] != WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT) {
2717                 assertEquals(evs[0], event.type);
2718                 assertEquals(evs[1], event.reason);
2719                 assertEquals(evs[2], event.status);
2720                 assertEquals(evs[3] == 1 ? true : false, event.localGen);
2721                 assertEquals(evs[4], event.authFailureReason);
2722                 assertEquals(evs[5] == 1 ? true : false, event.associationTimedOut);
2723                 assertEquals(evs[6], event.supplicantStateChangesBitmask);
2724                 assertConfigInfoEqualsWifiConfig(
2725                         evs[7] == 1 ? mTestWifiConfig : null, event.configInfo);
2726                 j++;
2727             }
2728         }
2729         for (int i = 0; i < mTestStaLogInts.length; i++) {
2730             StaEvent event = wifiLog.staEventList[j];
2731             int[] evs = mExpectedValues[j];
2732             assertEquals(evs[0], event.type);
2733             assertEquals(evs[1], event.reason);
2734             assertEquals(evs[2], event.status);
2735             assertEquals(evs[3] == 1 ? true : false, event.localGen);
2736             assertEquals(evs[4], event.authFailureReason);
2737             assertEquals(evs[5] == 1 ? true : false, event.associationTimedOut);
2738             assertEquals(evs[6], event.supplicantStateChangesBitmask);
2739             assertConfigInfoEqualsWifiConfig(
2740                     evs[7] == 1 ? mTestWifiConfig : null, event.configInfo);
2741             assertEquals(true, event.screenOn);
2742             assertEquals(true, event.isCellularDataAvailable);
2743             assertEquals(true, event.isAdaptiveConnectivityEnabled);
2744             j++;
2745         }
2746         assertEquals(mExpectedValues.length, j);
2747     }
2748 
2749     /**
2750      * Generate StaEvents of each type, ensure all the different values are logged correctly,
2751      * and that they survive serialization & de-serialization
2752      */
2753     @Test
testStaEventsLogSerializeDeserialize()2754     public void testStaEventsLogSerializeDeserialize() throws Exception {
2755         generateStaEvents(mWifiMetrics);
2756         dumpProtoAndDeserialize();
2757         verifyDeserializedStaEvents(mDecodedProto);
2758     }
2759 
2760     /**
2761      * Ensure the number of StaEvents does not exceed MAX_STA_EVENTS by generating lots of events
2762      * and checking how many are deserialized
2763      */
2764     @Test
testStaEventBounding()2765     public void testStaEventBounding() throws Exception {
2766         for (int i = 0; i < (WifiMetrics.MAX_STA_EVENTS + 10); i++) {
2767             mWifiMetrics.logStaEvent(TEST_IFACE_NAME, StaEvent.TYPE_CMD_START_CONNECT);
2768         }
2769         dumpProtoAndDeserialize();
2770         assertEquals(WifiMetrics.MAX_STA_EVENTS, mDecodedProto.staEventList.length);
2771     }
2772 
2773     /**
2774      * Tests that link probe StaEvents do not exceed
2775      * {@link WifiMetrics#MAX_LINK_PROBE_STA_EVENTS}.
2776      */
2777     @Test
testLinkProbeStaEventBounding()2778     public void testLinkProbeStaEventBounding() throws Exception {
2779         for (int i = 0; i < WifiMetrics.MAX_LINK_PROBE_STA_EVENTS; i++) {
2780             mWifiMetrics.logLinkProbeSuccess(TEST_IFACE_NAME, 0, 0, 0, 0);
2781             mWifiMetrics.logLinkProbeFailure(TEST_IFACE_NAME, 0, 0, 0, 0);
2782         }
2783         for (int i = 0; i < 10; i++) {
2784             mWifiMetrics.logStaEvent(TEST_IFACE_NAME, StaEvent.TYPE_CMD_START_CONNECT);
2785         }
2786 
2787         dumpProtoAndDeserialize();
2788 
2789         long numLinkProbeStaEvents = Arrays.stream(mDecodedProto.staEventList)
2790                 .filter(event -> event.type == TYPE_LINK_PROBE)
2791                 .count();
2792         assertEquals(WifiMetrics.MAX_LINK_PROBE_STA_EVENTS, numLinkProbeStaEvents);
2793         assertEquals(WifiMetrics.MAX_LINK_PROBE_STA_EVENTS + 10, mDecodedProto.staEventList.length);
2794     }
2795 
2796     /**
2797      * Test the logging of UserActionEvent with a valid network ID
2798      */
2799     @Test
testLogUserActionEventValidNetworkId()2800     public void testLogUserActionEventValidNetworkId() throws Exception {
2801         int testEventType = WifiMetricsProto.UserActionEvent.EVENT_FORGET_WIFI;
2802         int testNetworkId = 0;
2803         long testStartTimeMillis = 123123L;
2804         when(mClock.getElapsedSinceBootMillis()).thenReturn(testStartTimeMillis);
2805         WifiConfiguration config = WifiConfigurationTestUtil.createPasspointNetwork();
2806         config.ephemeral = true;
2807         when(mWcm.getConfiguredNetwork(testNetworkId)).thenReturn(config);
2808 
2809         mWifiMetrics.logUserActionEvent(testEventType, testNetworkId);
2810         dumpProtoAndDeserialize();
2811 
2812         WifiMetricsProto.UserActionEvent[] userActionEvents = mDecodedProto.userActionEvents;
2813         assertEquals(1, userActionEvents.length);
2814         assertEquals(WifiMetricsProto.UserActionEvent.EVENT_FORGET_WIFI,
2815                 userActionEvents[0].eventType);
2816         assertEquals(testStartTimeMillis, userActionEvents[0].startTimeMillis);
2817         assertEquals(true, userActionEvents[0].targetNetworkInfo.isEphemeral);
2818         assertEquals(true, userActionEvents[0].targetNetworkInfo.isPasspoint);
2819 
2820         // Verify that there are no disabled WifiConfiguration and BSSIDs
2821         NetworkDisableReason networkDisableReason = userActionEvents[0].networkDisableReason;
2822         assertEquals(NetworkDisableReason.REASON_UNKNOWN, networkDisableReason.disableReason);
2823         assertEquals(false, networkDisableReason.configTemporarilyDisabled);
2824         assertEquals(false, networkDisableReason.configPermanentlyDisabled);
2825         assertEquals(0, networkDisableReason.bssidDisableReasons.length);
2826     }
2827 
2828     /**
2829      * Verify the WifiStatus field in a UserActionEvent is populated correctly.
2830      * @throws Exception
2831      */
2832     @Test
testLogWifiStatusInUserActionEvent()2833     public void testLogWifiStatusInUserActionEvent() throws Exception {
2834         // setups WifiStatus for information
2835         int expectedRssi = -55;
2836         int testNetworkId = 1;
2837         int expectedTx = 1234;
2838         int expectedRx = 2345;
2839 
2840         WifiInfo wifiInfo = mock(WifiInfo.class);
2841         when(wifiInfo.getRssi()).thenReturn(expectedRssi);
2842         when(wifiInfo.getNetworkId()).thenReturn(testNetworkId);
2843         mWifiMetrics.handlePollResult(TEST_IFACE_NAME, wifiInfo);
2844         mWifiMetrics.incrementThroughputKbpsCount(expectedTx, expectedRx, RSSI_POLL_FREQUENCY);
2845         mWifiMetrics.setNominatorForNetwork(testNetworkId,
2846                 WifiMetricsProto.ConnectionEvent.NOMINATOR_SAVED_USER_CONNECT_CHOICE);
2847 
2848         // generate a user action event and then verify fields
2849         int testEventType = WifiMetricsProto.UserActionEvent.EVENT_FORGET_WIFI;
2850         mWifiMetrics.logUserActionEvent(testEventType, testNetworkId);
2851         dumpProtoAndDeserialize();
2852 
2853         WifiMetricsProto.UserActionEvent[] userActionEvents = mDecodedProto.userActionEvents;
2854         assertEquals(1, userActionEvents.length);
2855         assertEquals(WifiMetricsProto.UserActionEvent.EVENT_FORGET_WIFI,
2856                 userActionEvents[0].eventType);
2857         assertEquals(expectedRssi, userActionEvents[0].wifiStatus.lastRssi);
2858         assertEquals(expectedTx, userActionEvents[0].wifiStatus.estimatedTxKbps);
2859         assertEquals(expectedRx, userActionEvents[0].wifiStatus.estimatedRxKbps);
2860         assertTrue(userActionEvents[0].wifiStatus.isStuckDueToUserConnectChoice);
2861     }
2862 
2863     /**
2864      * verify NetworkDisableReason is populated properly when there exists a disabled
2865      * WifiConfiguration and BSSID.
2866      */
2867     @Test
testNetworkDisableReasonInUserActionEvent()2868     public void testNetworkDisableReasonInUserActionEvent() throws Exception {
2869         // Setup a temporarily blocked config due to DISABLED_ASSOCIATION_REJECTION
2870         WifiConfiguration testConfig = WifiConfigurationTestUtil.createOpenNetwork();
2871         NetworkSelectionStatus status = testConfig.getNetworkSelectionStatus();
2872         status.setNetworkSelectionStatus(
2873                 NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
2874         status.setNetworkSelectionDisableReason(
2875                 NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION);
2876         when(mWcm.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(testConfig);
2877 
2878         // Also setup the same BSSID level failure
2879         Set<Integer> testBssidBlocklistReasons = new HashSet<>();
2880         testBssidBlocklistReasons.add(WifiBlocklistMonitor.REASON_ASSOCIATION_REJECTION);
2881         when(mWifiBlocklistMonitor.getFailureReasonsForSsid(anyString()))
2882                 .thenReturn(testBssidBlocklistReasons);
2883 
2884         // Logging the user action event
2885         mWifiMetrics.logUserActionEvent(WifiMetricsProto.UserActionEvent.EVENT_FORGET_WIFI,
2886                 TEST_NETWORK_ID);
2887         dumpProtoAndDeserialize();
2888 
2889         WifiMetricsProto.UserActionEvent[] userActionEvents = mDecodedProto.userActionEvents;
2890         assertEquals(1, userActionEvents.length);
2891         assertEquals(WifiMetricsProto.UserActionEvent.EVENT_FORGET_WIFI,
2892                 userActionEvents[0].eventType);
2893         NetworkDisableReason networkDisableReason = userActionEvents[0].networkDisableReason;
2894         assertEquals(NetworkDisableReason.REASON_ASSOCIATION_REJECTION,
2895                 networkDisableReason.disableReason);
2896         assertEquals(true, networkDisableReason.configTemporarilyDisabled);
2897         assertEquals(false, networkDisableReason.configPermanentlyDisabled);
2898         assertEquals(1, networkDisableReason.bssidDisableReasons.length);
2899         assertEquals(NetworkDisableReason.REASON_ASSOCIATION_REJECTION,
2900                 networkDisableReason.bssidDisableReasons[0]);
2901     }
2902 
2903     /**
2904      * verify that auto-join disable overrides any other disable reasons in NetworkDisableReason.
2905      */
2906     @Test
testNetworkDisableReasonDisableAutojoinInUserActionEvent()2907     public void testNetworkDisableReasonDisableAutojoinInUserActionEvent() throws Exception {
2908         // Setup a temporarily blocked config due to DISABLED_ASSOCIATION_REJECTION
2909         WifiConfiguration testConfig = WifiConfigurationTestUtil.createOpenNetwork();
2910         NetworkSelectionStatus status = testConfig.getNetworkSelectionStatus();
2911         status.setNetworkSelectionStatus(
2912                 NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
2913         status.setNetworkSelectionDisableReason(
2914                 NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION);
2915         when(mWcm.getConfiguredNetwork(TEST_NETWORK_ID)).thenReturn(testConfig);
2916 
2917         // Disable autojoin
2918         testConfig.allowAutojoin = false;
2919 
2920         // Logging the user action event
2921         mWifiMetrics.logUserActionEvent(WifiMetricsProto.UserActionEvent.EVENT_FORGET_WIFI,
2922                 TEST_NETWORK_ID);
2923         dumpProtoAndDeserialize();
2924 
2925         WifiMetricsProto.UserActionEvent[] userActionEvents = mDecodedProto.userActionEvents;
2926         NetworkDisableReason networkDisableReason = userActionEvents[0].networkDisableReason;
2927         assertEquals(NetworkDisableReason.REASON_AUTO_JOIN_DISABLED,
2928                 networkDisableReason.disableReason);
2929         assertEquals(false, networkDisableReason.configTemporarilyDisabled);
2930         assertEquals(true, networkDisableReason.configPermanentlyDisabled);
2931     }
2932 
2933     /**
2934      * Test the logging of UserActionEvent with invalid network ID
2935      */
2936     @Test
testLogUserActionEventInvalidNetworkId()2937     public void testLogUserActionEventInvalidNetworkId() throws Exception {
2938         int testEventType = WifiMetricsProto.UserActionEvent.EVENT_FORGET_WIFI;
2939         int testNetworkId = 0;
2940         long testStartTimeMillis = 123123L;
2941         when(mClock.getElapsedSinceBootMillis()).thenReturn(testStartTimeMillis);
2942         when(mWcm.getConfiguredNetwork(testNetworkId)).thenReturn(null);
2943 
2944         mWifiMetrics.logUserActionEvent(testEventType, testNetworkId);
2945         dumpProtoAndDeserialize();
2946 
2947         WifiMetricsProto.UserActionEvent[] userActionEvents = mDecodedProto.userActionEvents;
2948         assertEquals(1, userActionEvents.length);
2949         assertEquals(WifiMetricsProto.UserActionEvent.EVENT_FORGET_WIFI,
2950                 userActionEvents[0].eventType);
2951         assertEquals(testStartTimeMillis, userActionEvents[0].startTimeMillis);
2952         assertNull(userActionEvents[0].targetNetworkInfo);
2953     }
2954 
2955     /**
2956      * Test the logging of UserActionEvent for Adaptive Connectivity toggle
2957      */
2958     @Test
testLogUserActionEventForAdaptiveConnectivity()2959     public void testLogUserActionEventForAdaptiveConnectivity() throws Exception {
2960         long testStartTimeMillis = 123123L;
2961         boolean adaptiveConnectivityEnabled = true;
2962         when(mClock.getElapsedSinceBootMillis()).thenReturn(testStartTimeMillis);
2963         mWifiMetrics.logUserActionEvent(
2964                 mWifiMetrics.convertAdaptiveConnectivityStateToUserActionEventType(
2965                         adaptiveConnectivityEnabled));
2966         long testStartTimeMillis2 = 200000L;
2967         boolean adaptiveConnectivityEnabled2 = false;
2968         when(mClock.getElapsedSinceBootMillis()).thenReturn(testStartTimeMillis2);
2969         mWifiMetrics.logUserActionEvent(
2970                 mWifiMetrics.convertAdaptiveConnectivityStateToUserActionEventType(
2971                         adaptiveConnectivityEnabled2));
2972         dumpProtoAndDeserialize();
2973 
2974         WifiMetricsProto.UserActionEvent[] userActionEvents = mDecodedProto.userActionEvents;
2975         assertEquals(2, userActionEvents.length);
2976         assertEquals(WifiMetricsProto.UserActionEvent.EVENT_CONFIGURE_ADAPTIVE_CONNECTIVITY_ON,
2977                 userActionEvents[0].eventType);
2978         assertEquals(testStartTimeMillis, userActionEvents[0].startTimeMillis);
2979         assertEquals(WifiMetricsProto.UserActionEvent.EVENT_CONFIGURE_ADAPTIVE_CONNECTIVITY_OFF,
2980                 userActionEvents[1].eventType);
2981         assertEquals(testStartTimeMillis2, userActionEvents[1].startTimeMillis);
2982     }
2983 
2984     /**
2985      * Verify that the max length of the UserActionEvent list is limited to MAX_USER_ACTION_EVENTS.
2986      */
2987     @Test
testLogUserActionEventCapped()2988     public void testLogUserActionEventCapped() throws Exception {
2989         for (int i = 0; i < WifiMetrics.MAX_USER_ACTION_EVENTS + 1; i++) {
2990             mWifiMetrics.logUserActionEvent(WifiMetricsProto.UserActionEvent.EVENT_FORGET_WIFI, 0);
2991         }
2992         dumpProtoAndDeserialize();
2993         assertEquals(WifiMetrics.MAX_USER_ACTION_EVENTS, mDecodedProto.userActionEvents.length);
2994     }
2995 
2996     /**
2997      * Ensure WifiMetrics doesn't cause a null pointer exception when called with null args
2998      */
2999     @Test
testDumpNullArg()3000     public void testDumpNullArg() {
3001         mWifiMetrics.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null);
3002     }
3003 
3004     /**
3005      * Test the generation of 'NumConnectableNetwork' histograms from two scans of different
3006      * ScanDetails produces the correct histogram values, and relevant bounds are observed
3007      */
3008     @MediumTest
3009     @Test
testNumConnectableNetworksGeneration()3010     public void testNumConnectableNetworksGeneration() throws Exception {
3011         List<ScanDetail> scan = new ArrayList<ScanDetail>();
3012         //                                ssid, bssid, isOpen, isSaved, isProvider, isWeakRssi)
3013         scan.add(buildMockScanDetail("PASSPOINT_1", "bssid0", false, false, true, false));
3014         scan.add(buildMockScanDetail("PASSPOINT_2", "bssid1", false, false, true, false));
3015         scan.add(buildMockScanDetail("SSID_B", "bssid2", true, true, false, false));
3016         scan.add(buildMockScanDetail("SSID_B", "bssid3", true, true, false, false));
3017         scan.add(buildMockScanDetail("SSID_C", "bssid4", true, false, false, false));
3018         scan.add(buildMockScanDetail("SSID_D", "bssid5", false, true, false, false));
3019         scan.add(buildMockScanDetail("SSID_E", "bssid6", false, true, false, false));
3020         scan.add(buildMockScanDetail("SSID_F", "bssid7", false, false, false, false));
3021         scan.add(buildMockScanDetail("SSID_G_WEAK", "bssid9", false, false, false, true));
3022         scan.add(buildMockScanDetail("SSID_H_WEAK", "bssid10", false, false, false, true));
3023         mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
3024         scan.add(buildMockScanDetail("SSID_B", "bssid8", true, true, false, false));
3025         mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
3026         for (int i = 0; i < NUM_PARTIAL_SCAN_RESULTS; i++) {
3027             mWifiMetrics.incrementAvailableNetworksHistograms(scan, false);
3028         }
3029         dumpProtoAndDeserialize();
3030         verifyHist(mDecodedProto.totalSsidsInScanHistogram, 1,                    a(7),    a(2));
3031         verifyHist(mDecodedProto.totalBssidsInScanHistogram, 2,                   a(8, 9), a(1, 1));
3032         verifyHist(mDecodedProto.availableOpenSsidsInScanHistogram, 1,            a(2),    a(2));
3033         verifyHist(mDecodedProto.availableOpenBssidsInScanHistogram, 2,           a(3, 4), a(1, 1));
3034         verifyHist(mDecodedProto.availableSavedSsidsInScanHistogram, 1,           a(3),    a(2));
3035         verifyHist(mDecodedProto.availableSavedBssidsInScanHistogram, 2,          a(4, 5), a(1, 1));
3036         verifyHist(mDecodedProto.availableOpenOrSavedSsidsInScanHistogram, 1,     a(4),    a(2));
3037         verifyHist(mDecodedProto.availableOpenOrSavedBssidsInScanHistogram, 2,    a(5, 6), a(1, 1));
3038         verifyHist(mDecodedProto.availableSavedPasspointProviderProfilesInScanHistogram, 1,
3039                                                                                   a(2),    a(2));
3040         verifyHist(mDecodedProto.availableSavedPasspointProviderBssidsInScanHistogram, 1,
3041                                                                                   a(2),    a(2));
3042         assertEquals(2, mDecodedProto.fullBandAllSingleScanListenerResults);
3043         assertEquals(NUM_PARTIAL_SCAN_RESULTS, mDecodedProto.partialAllSingleScanListenerResults);
3044 
3045         // Check Bounds
3046         scan.clear();
3047         int lotsOfSSids = Math.max(WifiMetrics.MAX_TOTAL_SCAN_RESULT_SSIDS_BUCKET,
3048                 WifiMetrics.MAX_CONNECTABLE_SSID_NETWORK_BUCKET) + 5;
3049         for (int i = 0; i < lotsOfSSids; i++) {
3050             scan.add(buildMockScanDetail("SSID_" + i, "bssid_" + i, true, true, false, false));
3051         }
3052         mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
3053         dumpProtoAndDeserialize();
3054         verifyHist(mDecodedProto.totalSsidsInScanHistogram, 1,
3055                 a(WifiMetrics.MAX_TOTAL_SCAN_RESULT_SSIDS_BUCKET), a(1));
3056         verifyHist(mDecodedProto.availableOpenSsidsInScanHistogram, 1,
3057                 a(WifiMetrics.MAX_CONNECTABLE_SSID_NETWORK_BUCKET), a(1));
3058         verifyHist(mDecodedProto.availableSavedSsidsInScanHistogram, 1,
3059                 a(WifiMetrics.MAX_CONNECTABLE_SSID_NETWORK_BUCKET), a(1));
3060         verifyHist(mDecodedProto.availableOpenOrSavedSsidsInScanHistogram, 1,
3061                 a(WifiMetrics.MAX_CONNECTABLE_SSID_NETWORK_BUCKET), a(1));
3062         scan.clear();
3063         int lotsOfBssids = Math.max(WifiMetrics.MAX_TOTAL_SCAN_RESULTS_BUCKET,
3064                 WifiMetrics.MAX_CONNECTABLE_BSSID_NETWORK_BUCKET) + 5;
3065         for (int i = 0; i < lotsOfBssids; i++) {
3066             scan.add(buildMockScanDetail("SSID", "bssid_" + i, true, true, false, false));
3067         }
3068         mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
3069         dumpProtoAndDeserialize();
3070         verifyHist(mDecodedProto.totalBssidsInScanHistogram, 1,
3071                 a(WifiMetrics.MAX_TOTAL_SCAN_RESULTS_BUCKET), a(1));
3072         verifyHist(mDecodedProto.availableOpenBssidsInScanHistogram, 1,
3073                 a(WifiMetrics.MAX_CONNECTABLE_BSSID_NETWORK_BUCKET), a(1));
3074         verifyHist(mDecodedProto.availableSavedBssidsInScanHistogram, 1,
3075                 a(WifiMetrics.MAX_CONNECTABLE_BSSID_NETWORK_BUCKET), a(1));
3076         verifyHist(mDecodedProto.availableOpenOrSavedBssidsInScanHistogram, 1,
3077                 a(WifiMetrics.MAX_CONNECTABLE_BSSID_NETWORK_BUCKET), a(1));
3078     }
3079 
3080     /**
3081      * Test that Hotspot 2.0 (Passpoint) scan results are collected correctly and that relevant
3082      * bounds are observed.
3083      */
3084     @Test
testObservedHotspotAps()3085     public void testObservedHotspotAps() throws Exception {
3086         List<ScanDetail> scan = new ArrayList<ScanDetail>();
3087         // 2 R1 (Unknown AP isn't counted) passpoint APs belonging to a single provider: hessid1
3088         long hessid1 = 10;
3089         int anqpDomainId1 = 5;
3090         scan.add(buildMockScanDetailPasspoint("PASSPOINT_XX", "00:02:03:04:05:06", hessid1,
3091                 anqpDomainId1, NetworkDetail.HSRelease.R1, true));
3092         scan.add(buildMockScanDetailPasspoint("PASSPOINT_XY", "01:02:03:04:05:06", hessid1,
3093                 anqpDomainId1, NetworkDetail.HSRelease.R1, true));
3094         scan.add(buildMockScanDetailPasspoint("PASSPOINT_XYZ", "02:02:03:04:05:06", hessid1,
3095                 anqpDomainId1, NetworkDetail.HSRelease.Unknown, true));
3096         // 2 R2 passpoint APs belonging to a single provider: hessid2
3097         long hessid2 = 12;
3098         int anqpDomainId2 = 6;
3099         scan.add(buildMockScanDetailPasspoint("PASSPOINT_Y", "AA:02:03:04:05:06", hessid2,
3100                 anqpDomainId2, NetworkDetail.HSRelease.R2, true));
3101         scan.add(buildMockScanDetailPasspoint("PASSPOINT_Z", "AB:02:03:04:05:06", hessid2,
3102                 anqpDomainId2, NetworkDetail.HSRelease.R2, true));
3103         mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
3104         scan = new ArrayList<ScanDetail>();
3105         // 3 R2 passpoint APs belonging to a single provider: hessid3 (in next scan)
3106         long hessid3 = 15;
3107         int anqpDomainId3 = 8;
3108         scan.add(buildMockScanDetailPasspoint("PASSPOINT_Y", "AA:02:03:04:05:06", hessid3,
3109                 anqpDomainId3, NetworkDetail.HSRelease.R2, true));
3110         scan.add(buildMockScanDetailPasspoint("PASSPOINT_Y", "AA:02:03:04:05:06", hessid3,
3111                 anqpDomainId3, NetworkDetail.HSRelease.R2, false));
3112         scan.add(buildMockScanDetailPasspoint("PASSPOINT_Z", "AB:02:03:04:05:06", hessid3,
3113                 anqpDomainId3, NetworkDetail.HSRelease.R2, true));
3114         // 2 R3 Passpoint APs belonging to a single provider: hessid4
3115         long hessid4 = 17;
3116         int anqpDomainId4 = 2;
3117         scan.add(buildMockScanDetailPasspoint("PASSPOINT_R3", "0C:02:03:04:05:01", hessid4,
3118                 anqpDomainId4, NetworkDetail.HSRelease.R3, true));
3119         scan.add(buildMockScanDetailPasspoint("PASSPOINT_R3_2", "0C:02:03:04:05:02", hessid4,
3120                 anqpDomainId4, NetworkDetail.HSRelease.R3, true));
3121         mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
3122         dumpProtoAndDeserialize();
3123 
3124         verifyHist(mDecodedProto.observedHotspotR1ApsInScanHistogram, 2, a(0, 2), a(1, 1));
3125         verifyHist(mDecodedProto.observedHotspotR2ApsInScanHistogram, 2, a(2, 3), a(1, 1));
3126         verifyHist(mDecodedProto.observedHotspotR3ApsInScanHistogram, 2, a(0, 2), a(1, 1));
3127         verifyHist(mDecodedProto.observedHotspotR1EssInScanHistogram, 2, a(0, 1), a(1, 1));
3128         verifyHist(mDecodedProto.observedHotspotR2EssInScanHistogram, 1, a(1), a(2));
3129         verifyHist(mDecodedProto.observedHotspotR3EssInScanHistogram, 2, a(0, 1), a(1, 1));
3130         verifyHist(mDecodedProto.observedHotspotR1ApsPerEssInScanHistogram, 1, a(2), a(1));
3131         verifyHist(mDecodedProto.observedHotspotR2ApsPerEssInScanHistogram, 2, a(2, 3), a(1, 1));
3132         verifyHist(mDecodedProto.observedHotspotR3ApsPerEssInScanHistogram, 1, a(2), a(1));
3133 
3134         // check bounds
3135         scan.clear();
3136         int lotsOfSSids = Math.max(WifiMetrics.MAX_TOTAL_PASSPOINT_APS_BUCKET,
3137                 WifiMetrics.MAX_TOTAL_PASSPOINT_UNIQUE_ESS_BUCKET) + 5;
3138         for (int i = 0; i < lotsOfSSids; i++) {
3139             scan.add(buildMockScanDetailPasspoint("PASSPOINT_XX" + i, "00:02:03:04:05:06", i,
3140                     i + 10, NetworkDetail.HSRelease.R1, true));
3141             scan.add(buildMockScanDetailPasspoint("PASSPOINT_XY" + i, "AA:02:03:04:05:06", 1000 * i,
3142                     i + 10, NetworkDetail.HSRelease.R2, false));
3143             scan.add(buildMockScanDetailPasspoint("PASSPOINT_XZ" + i, "0B:02:03:04:05:06", 101 * i,
3144                     i + 10, NetworkDetail.HSRelease.R3, false));
3145         }
3146         mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
3147         dumpProtoAndDeserialize();
3148         verifyHist(mDecodedProto.observedHotspotR1ApsInScanHistogram, 1,
3149                 a(WifiMetrics.MAX_TOTAL_PASSPOINT_APS_BUCKET), a(1));
3150         verifyHist(mDecodedProto.observedHotspotR2ApsInScanHistogram, 1,
3151                 a(WifiMetrics.MAX_TOTAL_PASSPOINT_APS_BUCKET), a(1));
3152         verifyHist(mDecodedProto.observedHotspotR3ApsInScanHistogram, 1,
3153                 a(WifiMetrics.MAX_TOTAL_PASSPOINT_APS_BUCKET), a(1));
3154         verifyHist(mDecodedProto.observedHotspotR1EssInScanHistogram, 1,
3155                 a(WifiMetrics.MAX_TOTAL_PASSPOINT_UNIQUE_ESS_BUCKET), a(1));
3156         verifyHist(mDecodedProto.observedHotspotR2EssInScanHistogram, 1,
3157                 a(WifiMetrics.MAX_TOTAL_PASSPOINT_UNIQUE_ESS_BUCKET), a(1));
3158         verifyHist(mDecodedProto.observedHotspotR3EssInScanHistogram, 1,
3159                 a(WifiMetrics.MAX_TOTAL_PASSPOINT_UNIQUE_ESS_BUCKET), a(1));
3160     }
3161 
3162     /**
3163      * Test that IEEE 802.11mc scan results are collected correctly and that relevant
3164      * bounds are observed.
3165      */
3166     @Test
testObserved80211mcAps()3167     public void testObserved80211mcAps() throws Exception {
3168         ScanDetail mockScanDetailNon80211mc = mock(ScanDetail.class);
3169         ScanDetail mockScanDetail80211mc = mock(ScanDetail.class);
3170         NetworkDetail mockNetworkDetailNon80211mc = mock(NetworkDetail.class);
3171         NetworkDetail mockNetworkDetail80211mc = mock(NetworkDetail.class);
3172         when(mockNetworkDetail80211mc.is80211McResponderSupport()).thenReturn(true);
3173         ScanResult mockScanResult = mock(ScanResult.class);
3174         mockScanResult.capabilities = "";
3175         when(mockScanDetailNon80211mc.getNetworkDetail()).thenReturn(mockNetworkDetailNon80211mc);
3176         when(mockScanDetail80211mc.getNetworkDetail()).thenReturn(mockNetworkDetail80211mc);
3177         when(mockScanDetailNon80211mc.getScanResult()).thenReturn(mockScanResult);
3178         when(mockScanDetail80211mc.getScanResult()).thenReturn(mockScanResult);
3179         when(mWns.isSignalTooWeak(eq(mockScanDetail80211mc.getScanResult()))).thenReturn(true);
3180         List<ScanDetail> scan = new ArrayList<ScanDetail>();
3181 
3182         // 4 scans (a few non-802.11mc supporting APs on each)
3183         //  scan1: no 802.11mc supporting APs
3184 
3185         scan.add(mockScanDetailNon80211mc);
3186         scan.add(mockScanDetailNon80211mc);
3187         mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
3188 
3189         //  scan2: 2 802.11mc supporting APs
3190         scan.clear();
3191         scan.add(mockScanDetailNon80211mc);
3192         scan.add(mockScanDetail80211mc);
3193         scan.add(mockScanDetail80211mc);
3194         mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
3195 
3196         //  scan3: 100 802.11mc supporting APs (> limit)
3197         scan.clear();
3198         scan.add(mockScanDetailNon80211mc);
3199         scan.add(mockScanDetailNon80211mc);
3200         scan.add(mockScanDetailNon80211mc);
3201         for (int i = 0; i < 100; ++i) {
3202             scan.add(mockScanDetail80211mc);
3203         }
3204         mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
3205 
3206         //  scan4: 2 802.11mc supporting APs
3207         scan.clear();
3208         scan.add(mockScanDetailNon80211mc);
3209         scan.add(mockScanDetail80211mc);
3210         scan.add(mockScanDetail80211mc);
3211         scan.add(mockScanDetailNon80211mc);
3212         mWifiMetrics.incrementAvailableNetworksHistograms(scan, true);
3213 
3214         dumpProtoAndDeserialize();
3215 
3216         verifyHist(mDecodedProto.observed80211McSupportingApsInScanHistogram, 3,
3217                 a(0, 2, WifiMetrics.MAX_TOTAL_80211MC_APS_BUCKET), a(1, 2, 1));
3218     }
3219 
3220     /**
3221      * Test Open Network Notification blocklist size and feature state are not cleared when proto
3222      * is dumped.
3223      */
3224     @Test
testOpenNetworkNotificationBlocklistSizeAndFeatureStateNotCleared()3225     public void testOpenNetworkNotificationBlocklistSizeAndFeatureStateNotCleared()
3226             throws Exception {
3227         mWifiMetrics.setNetworkRecommenderBlocklistSize(OPEN_NET_NOTIFIER_TAG,
3228                 SIZE_OPEN_NETWORK_RECOMMENDER_BLOCKLIST);
3229         mWifiMetrics.setIsWifiNetworksAvailableNotificationEnabled(OPEN_NET_NOTIFIER_TAG,
3230                 IS_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON);
3231         for (int i = 0; i < NUM_OPEN_NETWORK_RECOMMENDATION_UPDATES; i++) {
3232             mWifiMetrics.incrementNumNetworkRecommendationUpdates(OPEN_NET_NOTIFIER_TAG);
3233         }
3234 
3235         // This should clear most metrics in mWifiMetrics
3236         dumpProtoAndDeserialize();
3237         assertEquals(SIZE_OPEN_NETWORK_RECOMMENDER_BLOCKLIST,
3238                 mDecodedProto.openNetworkRecommenderBlocklistSize);
3239         assertEquals(IS_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
3240                 mDecodedProto.isWifiNetworksAvailableNotificationOn);
3241         assertEquals(NUM_OPEN_NETWORK_RECOMMENDATION_UPDATES,
3242                 mDecodedProto.numOpenNetworkRecommendationUpdates);
3243 
3244         // Check that blocklist size and feature state persist on next dump but
3245         // others do not.
3246         dumpProtoAndDeserialize();
3247         assertEquals(SIZE_OPEN_NETWORK_RECOMMENDER_BLOCKLIST,
3248                 mDecodedProto.openNetworkRecommenderBlocklistSize);
3249         assertEquals(IS_WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
3250                 mDecodedProto.isWifiNetworksAvailableNotificationOn);
3251         assertEquals(0, mDecodedProto.numOpenNetworkRecommendationUpdates);
3252     }
3253 
3254     /**
3255      * Check network selector id
3256      */
3257     @Test
testNetworkSelectorExperimentId()3258     public void testNetworkSelectorExperimentId() throws Exception {
3259         final int id = 42888888;
3260         mWifiMetrics.setNetworkSelectorExperimentId(id);
3261         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, mTestWifiConfig,
3262                 "TestNetwork", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
3263         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
3264                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
3265                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
3266                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
3267         dumpProtoAndDeserialize();
3268         assertEquals(id, mDecodedProto.connectionEvent[0].networkSelectorExperimentId);
3269     }
3270 
3271     /**
3272      * Check pmk cache
3273      */
3274     @Test
testConnectionWithPmkCache()3275     public void testConnectionWithPmkCache() throws Exception {
3276         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, mTestWifiConfig,
3277                 "TestNetwork", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
3278         mWifiMetrics.setConnectionPmkCache(TEST_IFACE_NAME, true);
3279         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
3280                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
3281                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
3282                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
3283         dumpProtoAndDeserialize();
3284         assertEquals(true, mDecodedProto.connectionEvent[0].routerFingerprint.pmkCacheEnabled);
3285     }
3286 
3287     /**
3288      * Check max supported link speed and consecutive connection failure count
3289      */
3290     @Test
testConnectionMaxSupportedLinkSpeedConsecutiveFailureCnt()3291     public void testConnectionMaxSupportedLinkSpeedConsecutiveFailureCnt() throws Exception {
3292         setScreenState(true);
3293         when(mNetworkConnectionStats.getCount(WifiScoreCard.CNT_CONSECUTIVE_CONNECTION_FAILURE))
3294                 .thenReturn(2);
3295         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, mTestWifiConfig,
3296                 "TestNetwork", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
3297         mWifiMetrics.setConnectionMaxSupportedLinkSpeedMbps(TEST_IFACE_NAME,
3298                 MAX_SUPPORTED_TX_LINK_SPEED_MBPS, MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
3299         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
3300                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
3301                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
3302                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
3303         dumpProtoAndDeserialize();
3304         assertEquals(MAX_SUPPORTED_TX_LINK_SPEED_MBPS, mDecodedProto.connectionEvent[0]
3305                 .routerFingerprint.maxSupportedTxLinkSpeedMbps);
3306         assertEquals(MAX_SUPPORTED_RX_LINK_SPEED_MBPS, mDecodedProto.connectionEvent[0]
3307                 .routerFingerprint.maxSupportedRxLinkSpeedMbps);
3308         assertEquals(2, mDecodedProto.connectionEvent[0].numConsecutiveConnectionFailure);
3309         assertEquals(true, mDecodedProto.connectionEvent[0].screenOn);
3310     }
3311 
3312     /**
3313      * Check ScoringParams
3314      */
3315     @Test
testExperimentId()3316     public void testExperimentId() throws Exception {
3317         final int id = 42;
3318         final String expectId = "x" + id;
3319         when(mScoringParams.getExperimentIdentifier()).thenReturn(id);
3320         dumpProtoAndDeserialize();
3321         assertEquals(expectId, mDecodedProto.scoreExperimentId);
3322     }
3323 
3324     /**
3325      * Check ScoringParams default case
3326      */
3327     @Test
testDefaultExperimentId()3328     public void testDefaultExperimentId() throws Exception {
3329         final int id = 0;
3330         final String expectId = "";
3331         when(mScoringParams.getExperimentIdentifier()).thenReturn(id);
3332         dumpProtoAndDeserialize();
3333         assertEquals(expectId, mDecodedProto.scoreExperimentId);
3334     }
3335 
3336     /** short hand for instantiating an anonymous int array, instead of 'new int[]{a1, a2, ...}' */
a(int... element)3337     private int[] a(int... element) {
3338         return element;
3339     }
3340 
verifyHist(WifiMetricsProto.NumConnectableNetworksBucket[] hist, int size, int[] keys, int[] counts)3341     private void verifyHist(WifiMetricsProto.NumConnectableNetworksBucket[] hist, int size,
3342             int[] keys, int[] counts) throws Exception {
3343         assertEquals(size, hist.length);
3344         for (int i = 0; i < keys.length; i++) {
3345             assertEquals(keys[i], hist[i].numConnectableNetworks);
3346             assertEquals(counts[i], hist[i].count);
3347         }
3348     }
3349 
3350     /**
3351      * Generate an RSSI delta event by creating a connection event and an RSSI poll within
3352      * 'interArrivalTime' milliseconds of each other.
3353      * Event will not be logged if interArrivalTime > mWifiMetrics.TIMEOUT_RSSI_DELTA_MILLIS
3354      * successfulConnectionEvent, completeConnectionEvent, useValidScanResult and
3355      * dontDeserializeBeforePoll
3356      * each create an anomalous condition when set to false.
3357      */
generateRssiDelta(int scanRssi, int rssiDelta, long interArrivalTime, boolean successfulConnectionEvent, boolean completeConnectionEvent, boolean useValidScanResult, boolean dontDeserializeBeforePoll)3358     private void generateRssiDelta(int scanRssi, int rssiDelta,
3359             long interArrivalTime, boolean successfulConnectionEvent,
3360             boolean completeConnectionEvent, boolean useValidScanResult,
3361             boolean dontDeserializeBeforePoll) throws Exception {
3362         when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 0);
3363         ScanResult scanResult = null;
3364         if (useValidScanResult) {
3365             scanResult = mock(ScanResult.class);
3366             scanResult.level = scanRssi;
3367         }
3368         WifiConfiguration config = mock(WifiConfiguration.class);
3369         WifiConfiguration.NetworkSelectionStatus networkSelectionStat =
3370                 mock(WifiConfiguration.NetworkSelectionStatus.class);
3371         config.allowedKeyManagement = new BitSet();
3372         when(networkSelectionStat.getCandidate()).thenReturn(scanResult);
3373         when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStat);
3374         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
3375                 "TestNetwork", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
3376         if (completeConnectionEvent) {
3377             if (successfulConnectionEvent) {
3378                 mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
3379                         WifiMetrics.ConnectionEvent.FAILURE_NONE,
3380                         WifiMetricsProto.ConnectionEvent.HLF_NONE,
3381                         WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
3382             } else {
3383                 mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
3384                         WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
3385                         WifiMetricsProto.ConnectionEvent.HLF_NONE,
3386                         WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
3387             }
3388         }
3389         when(mClock.getElapsedSinceBootMillis()).thenReturn(interArrivalTime);
3390         if (!dontDeserializeBeforePoll) {
3391             dumpProtoAndDeserialize();
3392         }
3393         mWifiMetrics.incrementRssiPollRssiCount(RSSI_POLL_FREQUENCY, scanRssi + rssiDelta);
3394     }
3395 
3396     /**
3397      * Generate an RSSI delta event, with all extra conditions set to true.
3398      */
generateRssiDelta(int scanRssi, int rssiDelta, long interArrivalTime)3399     private void generateRssiDelta(int scanRssi, int rssiDelta,
3400             long interArrivalTime) throws Exception {
3401         generateRssiDelta(scanRssi, rssiDelta, interArrivalTime, true, true, true, true);
3402     }
3403 
assertStringContains( String actualString, String expectedSubstring)3404     private void assertStringContains(
3405             String actualString, String expectedSubstring) {
3406         assertTrue("Expected text not found in: " + actualString,
3407                 actualString.contains(expectedSubstring));
3408     }
3409 
getStateDump()3410     private String getStateDump() {
3411         ByteArrayOutputStream stream = new ByteArrayOutputStream();
3412         PrintWriter writer = new PrintWriter(stream);
3413         String[] args = new String[0];
3414         mWifiMetrics.dump(null, writer, args);
3415         writer.flush();
3416         return stream.toString();
3417     }
3418 
3419     private static final int TEST_ALLOWED_KEY_MANAGEMENT = 16;
3420     private static final int TEST_ALLOWED_PROTOCOLS = 22;
3421     private static final int TEST_ALLOWED_AUTH_ALGORITHMS = 11;
3422     private static final int TEST_ALLOWED_PAIRWISE_CIPHERS = 67;
3423     private static final int TEST_ALLOWED_GROUP_CIPHERS = 231;
3424     private static final int TEST_CANDIDATE_LEVEL = -80;
3425     private static final int TEST_CANDIDATE_FREQ = 2450;
3426 
createComplexWifiConfig()3427     private WifiConfiguration createComplexWifiConfig() {
3428         WifiConfiguration config = new WifiConfiguration();
3429         config.SSID = SSID;
3430         config.allowedKeyManagement = intToBitSet(TEST_ALLOWED_KEY_MANAGEMENT);
3431         config.allowedProtocols = intToBitSet(TEST_ALLOWED_PROTOCOLS);
3432         config.allowedAuthAlgorithms = intToBitSet(TEST_ALLOWED_AUTH_ALGORITHMS);
3433         config.allowedPairwiseCiphers = intToBitSet(TEST_ALLOWED_PAIRWISE_CIPHERS);
3434         config.allowedGroupCiphers = intToBitSet(TEST_ALLOWED_GROUP_CIPHERS);
3435         config.hiddenSSID = true;
3436         config.ephemeral = true;
3437         config.getNetworkSelectionStatus().setHasEverConnected(true);
3438         ScanResult candidate = new ScanResult();
3439         candidate.level = TEST_CANDIDATE_LEVEL;
3440         candidate.frequency = TEST_CANDIDATE_FREQ;
3441         config.getNetworkSelectionStatus().setCandidate(candidate);
3442         return config;
3443     }
3444 
assertConfigInfoEqualsWifiConfig(WifiConfiguration config, StaEvent.ConfigInfo info)3445     private void assertConfigInfoEqualsWifiConfig(WifiConfiguration config,
3446             StaEvent.ConfigInfo info) {
3447         if (config == null && info == null) return;
3448         assertEquals(config.allowedKeyManagement,   intToBitSet(info.allowedKeyManagement));
3449         assertEquals(config.allowedProtocols,       intToBitSet(info.allowedProtocols));
3450         assertEquals(config.allowedAuthAlgorithms,  intToBitSet(info.allowedAuthAlgorithms));
3451         assertEquals(config.allowedPairwiseCiphers, intToBitSet(info.allowedPairwiseCiphers));
3452         assertEquals(config.allowedGroupCiphers,    intToBitSet(info.allowedGroupCiphers));
3453         assertEquals(config.hiddenSSID, info.hiddenSsid);
3454         assertEquals(config.ephemeral, info.isEphemeral);
3455         assertEquals(config.getNetworkSelectionStatus().hasEverConnected(),
3456                 info.hasEverConnected);
3457         assertEquals(config.getNetworkSelectionStatus().getCandidate().level, info.scanRssi);
3458         assertEquals(config.getNetworkSelectionStatus().getCandidate().frequency, info.scanFreq);
3459     }
3460 
3461     /**
3462      * Sets the values of bitSet to match an int mask
3463      */
intToBitSet(int mask)3464     private static BitSet intToBitSet(int mask) {
3465         BitSet bitSet = new BitSet();
3466         for (int bitIndex = 0; mask > 0; mask >>>= 1, bitIndex++) {
3467             if ((mask & 1) != 0) bitSet.set(bitIndex);
3468         }
3469         return bitSet;
3470     }
3471 
3472     private static final int NUM_UNUSABLE_EVENT = 5;
3473     private static final int NUM_UNUSABLE_EVENT_TIME_THROTTLE = 3;
3474 
3475     /**
3476      * Values used to generate WifiIsUnusableEvent
3477      * <WifiIsUnusableEvent.TriggerType>, <last_score>, <tx_success_delta>, <tx_retries_delta>,
3478      * <tx_bad_delta>, <rx_success_delta>, <packet_update_time_delta>, <firmware_alert_code>,
3479      * <last_wifi_usability_score>, <mobile_tx_bytes>, <mobile_rx_bytes>, <total_tx_bytes>,
3480      * <total_rx_bytes>,
3481      */
3482     private int[][] mTestUnusableEvents = {
3483         {WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX,        60,  60,  50,  40,  30,  1000,  -1, 51,
3484                 11, 12, 13, 14},
3485         {WifiIsUnusableEvent.TYPE_DATA_STALL_TX_WITHOUT_RX, 55,  40,  30,  0,   0,   500,   -1, 52,
3486                 15, 16, 17, 18},
3487         {WifiIsUnusableEvent.TYPE_DATA_STALL_BOTH,          60,  90,  30,  30,  0,   1000,  -1, 53,
3488                 19, 20, 21, 22},
3489         {WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT,           55,  55,  30,  15,  10,  1000,   4, 54,
3490                 23, 24, 25, 26},
3491         {WifiIsUnusableEvent.TYPE_IP_REACHABILITY_LOST,     50,  56,  28,  17,  12,  1000,  -1, 45,
3492                 27, 28, 29, 30}
3493     };
3494 
3495     /**
3496      * Generate all WifiIsUnusableEvents from mTestUnusableEvents
3497      */
generateAllUnusableEvents(WifiMetrics wifiMetrics)3498     private void generateAllUnusableEvents(WifiMetrics wifiMetrics) {
3499         for (int i = 0; i < mTestUnusableEvents.length; i++) {
3500             generateUnusableEventAtGivenTime(i, i * (WifiMetrics.MIN_DATA_STALL_WAIT_MS + 1000));
3501         }
3502     }
3503 
3504     /**
3505      * Generate a WifiIsUnusableEvent at the given timestamp with data from
3506      * mTestUnusableEvents[index]
3507      */
generateUnusableEventAtGivenTime(int index, long eventTime)3508     private void generateUnusableEventAtGivenTime(int index, long eventTime) {
3509         when(mClock.getElapsedSinceBootMillis()).thenReturn(eventTime);
3510         int[] trigger = mTestUnusableEvents[index];
3511         when(mFacade.getMobileTxBytes()).thenReturn((long) trigger[9]);
3512         when(mFacade.getMobileRxBytes()).thenReturn((long) trigger[10]);
3513         when(mFacade.getTotalTxBytes()).thenReturn((long) trigger[11]);
3514         when(mFacade.getTotalRxBytes()).thenReturn((long) trigger[12]);
3515         mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, trigger[1]);
3516         mWifiMetrics.incrementWifiUsabilityScoreCount(TEST_IFACE_NAME, 1, trigger[8], 15);
3517         mWifiMetrics.updateWifiIsUnusableLinkLayerStats(trigger[2], trigger[3], trigger[4],
3518                 trigger[5], trigger[6]);
3519         setScreenState(true);
3520         switch(trigger[0]) {
3521             case WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX:
3522             case WifiIsUnusableEvent.TYPE_DATA_STALL_TX_WITHOUT_RX:
3523             case WifiIsUnusableEvent.TYPE_DATA_STALL_BOTH:
3524                 mWifiMetrics.logWifiIsUnusableEvent(TEST_IFACE_NAME, trigger[0]);
3525                 break;
3526             case WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT:
3527                 mWifiMetrics.logWifiIsUnusableEvent(TEST_IFACE_NAME, trigger[0], trigger[7]);
3528                 break;
3529             case WifiIsUnusableEvent.TYPE_IP_REACHABILITY_LOST:
3530                 mWifiMetrics.logWifiIsUnusableEvent(TEST_IFACE_NAME, trigger[0]);
3531                 break;
3532             default:
3533                 break;
3534         }
3535     }
3536 
3537     /**
3538      * Verify that WifiIsUnusableEvent in wifiLog matches mTestUnusableEvents
3539      */
verifyDeserializedUnusableEvents(WifiMetricsProto.WifiLog wifiLog)3540     private void verifyDeserializedUnusableEvents(WifiMetricsProto.WifiLog wifiLog) {
3541         assertEquals(NUM_UNUSABLE_EVENT, wifiLog.wifiIsUnusableEventList.length);
3542         for (int i = 0; i < mTestUnusableEvents.length; i++) {
3543             WifiIsUnusableEvent event = wifiLog.wifiIsUnusableEventList[i];
3544             verifyUnusableEvent(event, i);
3545         }
3546     }
3547 
3548     /**
3549      * Verify that the given WifiIsUnusableEvent matches mTestUnusableEvents
3550      * at given index
3551      */
verifyUnusableEvent(WifiIsUnusableEvent event, int index)3552     private void verifyUnusableEvent(WifiIsUnusableEvent event, int index) {
3553         int[] expectedValues = mTestUnusableEvents[index];
3554         assertEquals(expectedValues[0], event.type);
3555         assertEquals(expectedValues[1], event.lastScore);
3556         assertEquals(expectedValues[2], event.txSuccessDelta);
3557         assertEquals(expectedValues[3], event.txRetriesDelta);
3558         assertEquals(expectedValues[4], event.txBadDelta);
3559         assertEquals(expectedValues[5], event.rxSuccessDelta);
3560         assertEquals(expectedValues[6], event.packetUpdateTimeDelta);
3561         assertEquals(expectedValues[7], event.firmwareAlertCode);
3562         assertEquals(expectedValues[8], event.lastWifiUsabilityScore);
3563         assertEquals(true, event.screenOn);
3564         assertEquals(expectedValues[9], event.mobileTxBytes);
3565         assertEquals(expectedValues[10], event.mobileRxBytes);
3566         assertEquals(expectedValues[11], event.totalTxBytes);
3567         assertEquals(expectedValues[12], event.totalRxBytes);
3568     }
3569 
3570     /**
3571      * Verify that no WifiIsUnusableEvent is generated when it is disabled in the settings
3572      */
3573     @Test
testNoUnusableEventLogWhenDisabled()3574     public void testNoUnusableEventLogWhenDisabled() throws Exception {
3575         mResources.setBoolean(R.bool.config_wifiIsUnusableEventMetricsEnabled, false);
3576         generateAllUnusableEvents(mWifiMetrics);
3577         dumpProtoAndDeserialize();
3578         assertEquals(0, mDecodedProto.wifiIsUnusableEventList.length);
3579     }
3580 
3581     /**
3582      * Generate WifiIsUnusableEvent and verify that they are logged correctly
3583      */
3584     @Test
testUnusableEventLogSerializeDeserialize()3585     public void testUnusableEventLogSerializeDeserialize() throws Exception {
3586         mResources.setBoolean(R.bool.config_wifiIsUnusableEventMetricsEnabled, true);
3587         generateAllUnusableEvents(mWifiMetrics);
3588         dumpProtoAndDeserialize();
3589         verifyDeserializedUnusableEvents(mDecodedProto);
3590     }
3591 
3592     /**
3593      * Verify that the number of WifiIsUnusableEvents does not exceed MAX_UNUSABLE_EVENTS
3594      */
3595     @Test
testUnusableEventBounding()3596     public void testUnusableEventBounding() throws Exception {
3597         mResources.setBoolean(R.bool.config_wifiIsUnusableEventMetricsEnabled, true);
3598         for (int i = 0; i < (WifiMetrics.MAX_UNUSABLE_EVENTS + 2); i++) {
3599             generateAllUnusableEvents(mWifiMetrics);
3600         }
3601         dumpProtoAndDeserialize();
3602         assertEquals(WifiMetrics.MAX_UNUSABLE_EVENTS, mDecodedProto.wifiIsUnusableEventList.length);
3603     }
3604 
3605     /**
3606      * Verify that we don't generate new WifiIsUnusableEvent from data stalls
3607      * until MIN_DATA_STALL_WAIT_MS has passed since the last data stall WifiIsUnusableEvent
3608      */
3609     @Test
testUnusableEventTimeThrottleForDataStall()3610     public void testUnusableEventTimeThrottleForDataStall() throws Exception {
3611         mResources.setBoolean(R.bool.config_wifiIsUnusableEventMetricsEnabled, true);
3612         generateUnusableEventAtGivenTime(0, 0);
3613         // should be time throttled
3614         generateUnusableEventAtGivenTime(1, 1);
3615         generateUnusableEventAtGivenTime(2, WifiMetrics.MIN_DATA_STALL_WAIT_MS + 1000);
3616         // no time throttle for firmware alert
3617         generateUnusableEventAtGivenTime(3, WifiMetrics.MIN_DATA_STALL_WAIT_MS + 1001);
3618         dumpProtoAndDeserialize();
3619         assertEquals(NUM_UNUSABLE_EVENT_TIME_THROTTLE,
3620                 mDecodedProto.wifiIsUnusableEventList.length);
3621         verifyUnusableEvent(mDecodedProto.wifiIsUnusableEventList[0], 0);
3622         verifyUnusableEvent(mDecodedProto.wifiIsUnusableEventList[1], 2);
3623         verifyUnusableEvent(mDecodedProto.wifiIsUnusableEventList[2], 3);
3624     }
3625 
3626     /**
3627      * Verify that LinkSpeedCounts is correctly logged in metrics
3628      */
3629     @Test
testLinkSpeedCounts()3630     public void testLinkSpeedCounts() throws Exception {
3631         mResources.setBoolean(R.bool.config_wifiLinkSpeedMetricsEnabled, true);
3632         for (int i = 0; i < NUM_LINK_SPEED_LEVELS_TO_INCREMENT; i++) {
3633             for (int j = 0; j <= i; j++) {
3634                 mWifiMetrics.incrementLinkSpeedCount(
3635                         WifiMetrics.MIN_LINK_SPEED_MBPS + i, TEST_RSSI_LEVEL);
3636             }
3637         }
3638         dumpProtoAndDeserialize();
3639         assertEquals(NUM_LINK_SPEED_LEVELS_TO_INCREMENT, mDecodedProto.linkSpeedCounts.length);
3640         for (int i = 0; i < NUM_LINK_SPEED_LEVELS_TO_INCREMENT; i++) {
3641             assertEquals("Incorrect link speed", WifiMetrics.MIN_LINK_SPEED_MBPS + i,
3642                     mDecodedProto.linkSpeedCounts[i].linkSpeedMbps);
3643             assertEquals("Incorrect count of link speed",
3644                     i + 1, mDecodedProto.linkSpeedCounts[i].count);
3645             assertEquals("Incorrect sum of absolute values of rssi values",
3646                     Math.abs(TEST_RSSI_LEVEL) * (i + 1),
3647                     mDecodedProto.linkSpeedCounts[i].rssiSumDbm);
3648             assertEquals("Incorrect sum of squares of rssi values",
3649                     TEST_RSSI_LEVEL * TEST_RSSI_LEVEL * (i + 1),
3650                     mDecodedProto.linkSpeedCounts[i].rssiSumOfSquaresDbmSq);
3651         }
3652     }
3653 
3654     /**
3655      * Verify that Tx and Rx per-band LinkSpeedCounts are correctly logged in metrics
3656      */
3657     @Test
testTxRxLinkSpeedBandCounts()3658     public void testTxRxLinkSpeedBandCounts() throws Exception {
3659         mResources.setBoolean(R.bool.config_wifiLinkSpeedMetricsEnabled, true);
3660         for (int i = 0; i < NUM_LINK_SPEED_LEVELS_TO_INCREMENT; i++) {
3661             for (int j = 0; j <= i; j++) {
3662                 mWifiMetrics.incrementTxLinkSpeedBandCount(
3663                         WifiMetrics.MIN_LINK_SPEED_MBPS + i, RSSI_POLL_FREQUENCY);
3664                 mWifiMetrics.incrementRxLinkSpeedBandCount(
3665                         WifiMetrics.MIN_LINK_SPEED_MBPS + i + 1, RSSI_POLL_FREQUENCY);
3666             }
3667         }
3668         dumpProtoAndDeserialize();
3669         assertEquals(0, mDecodedProto.txLinkSpeedCount2G.length);
3670         assertEquals(0, mDecodedProto.rxLinkSpeedCount2G.length);
3671         assertEquals(NUM_LINK_SPEED_LEVELS_TO_INCREMENT,
3672                 mDecodedProto.txLinkSpeedCount5GLow.length);
3673         assertEquals(NUM_LINK_SPEED_LEVELS_TO_INCREMENT,
3674                 mDecodedProto.rxLinkSpeedCount5GLow.length);
3675         assertEquals(0, mDecodedProto.txLinkSpeedCount5GMid.length);
3676         assertEquals(0, mDecodedProto.rxLinkSpeedCount5GMid.length);
3677         assertEquals(0, mDecodedProto.txLinkSpeedCount5GHigh.length);
3678         assertEquals(0, mDecodedProto.rxLinkSpeedCount5GHigh.length);
3679         for (int i = 0; i < NUM_LINK_SPEED_LEVELS_TO_INCREMENT; i++) {
3680             assertEquals("Incorrect Tx link speed", WifiMetrics.MIN_LINK_SPEED_MBPS + i,
3681                     mDecodedProto.txLinkSpeedCount5GLow[i].key);
3682             assertEquals("Incorrect Rx link speed", WifiMetrics.MIN_LINK_SPEED_MBPS + i + 1,
3683                     mDecodedProto.rxLinkSpeedCount5GLow[i].key);
3684             assertEquals("Incorrect count of Tx link speed",
3685                     i + 1, mDecodedProto.txLinkSpeedCount5GLow[i].count);
3686             assertEquals("Incorrect count of Rx link speed",
3687                     i + 1, mDecodedProto.rxLinkSpeedCount5GLow[i].count);
3688         }
3689     }
3690 
3691     /**
3692      * Verify that LinkSpeedCounts is not logged when disabled in settings
3693      */
3694     @Test
testNoLinkSpeedCountsWhenDisabled()3695     public void testNoLinkSpeedCountsWhenDisabled() throws Exception {
3696         mResources.setBoolean(R.bool.config_wifiLinkSpeedMetricsEnabled, false);
3697         for (int i = 0; i < NUM_LINK_SPEED_LEVELS_TO_INCREMENT; i++) {
3698             for (int j = 0; j <= i; j++) {
3699                 mWifiMetrics.incrementLinkSpeedCount(
3700                         WifiMetrics.MIN_LINK_SPEED_MBPS + i, TEST_RSSI_LEVEL);
3701                 mWifiMetrics.incrementTxLinkSpeedBandCount(
3702                         WifiMetrics.MIN_LINK_SPEED_MBPS - i, RSSI_POLL_FREQUENCY);
3703                 mWifiMetrics.incrementRxLinkSpeedBandCount(
3704                         WifiMetrics.MIN_LINK_SPEED_MBPS - i, RSSI_POLL_FREQUENCY);
3705             }
3706         }
3707         dumpProtoAndDeserialize();
3708         assertEquals("LinkSpeedCounts should not be logged when disabled in settings",
3709                 0, mDecodedProto.linkSpeedCounts.length);
3710         assertEquals("Tx LinkSpeedCounts should not be logged when disabled in settings",
3711                 0, mDecodedProto.txLinkSpeedCount5GLow.length);
3712         assertEquals("Rx LinkSpeedCounts should not be logged when disabled in settings",
3713                 0, mDecodedProto.rxLinkSpeedCount5GLow.length);
3714     }
3715 
3716     /**
3717      * Verify that LinkSpeedCounts is not logged when the link speed value is lower than
3718      * MIN_LINK_SPEED_MBPS or when the rssi value is outside of
3719      * [MIN_RSSI_LEVEL, MAX_RSSI_LEVEL]
3720      */
3721     @Test
testNoLinkSpeedCountsForOutOfBoundValues()3722     public void testNoLinkSpeedCountsForOutOfBoundValues() throws Exception {
3723         mResources.setBoolean(R.bool.config_wifiLinkSpeedMetricsEnabled, true);
3724         for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
3725             mWifiMetrics.incrementLinkSpeedCount(
3726                     WifiMetrics.MIN_LINK_SPEED_MBPS - i, MIN_RSSI_LEVEL);
3727             mWifiMetrics.incrementTxLinkSpeedBandCount(
3728                     WifiMetrics.MIN_LINK_SPEED_MBPS - i, RSSI_POLL_FREQUENCY);
3729             mWifiMetrics.incrementRxLinkSpeedBandCount(
3730                     WifiMetrics.MIN_LINK_SPEED_MBPS - i, RSSI_POLL_FREQUENCY);
3731         }
3732         for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
3733             mWifiMetrics.incrementLinkSpeedCount(
3734                     WifiMetrics.MIN_LINK_SPEED_MBPS, MIN_RSSI_LEVEL - i);
3735         }
3736         for (int i = 1; i < NUM_OUT_OF_BOUND_ENTRIES; i++) {
3737             mWifiMetrics.incrementLinkSpeedCount(
3738                     WifiMetrics.MIN_LINK_SPEED_MBPS, MAX_RSSI_LEVEL + i);
3739         }
3740         dumpProtoAndDeserialize();
3741         assertEquals("LinkSpeedCounts should not be logged for out of bound values",
3742                 0, mDecodedProto.linkSpeedCounts.length);
3743         assertEquals("Tx LinkSpeedCounts should not be logged for out of bound values",
3744                 0, mDecodedProto.txLinkSpeedCount5GLow.length);
3745         assertEquals("Rx LinkSpeedCounts should not be logged for out of bound values",
3746                 0, mDecodedProto.rxLinkSpeedCount5GLow.length);
3747     }
3748 
nextRandInt()3749     private int nextRandInt() {
3750         return mRandom.nextInt(1000);
3751     }
3752 
nextRandomStats(WifiLinkLayerStats current)3753     private WifiLinkLayerStats nextRandomStats(WifiLinkLayerStats current) {
3754         WifiLinkLayerStats out = new WifiLinkLayerStats();
3755         out.timeStampInMs = current.timeStampInMs + nextRandInt();
3756 
3757         out.rxmpdu_be = current.rxmpdu_be + nextRandInt();
3758         out.txmpdu_be = current.txmpdu_be + nextRandInt();
3759         out.lostmpdu_be = current.lostmpdu_be + nextRandInt();
3760         out.retries_be = current.retries_be + nextRandInt();
3761 
3762         out.rxmpdu_bk = current.rxmpdu_bk + nextRandInt();
3763         out.txmpdu_bk = current.txmpdu_bk + nextRandInt();
3764         out.lostmpdu_bk = current.lostmpdu_bk + nextRandInt();
3765         out.retries_bk = current.retries_bk + nextRandInt();
3766 
3767         out.rxmpdu_vi = current.rxmpdu_vi + nextRandInt();
3768         out.txmpdu_vi = current.txmpdu_vi + nextRandInt();
3769         out.lostmpdu_vi = current.lostmpdu_vi + nextRandInt();
3770         out.retries_vi = current.retries_vi + nextRandInt();
3771 
3772         out.rxmpdu_vo = current.rxmpdu_vo + nextRandInt();
3773         out.txmpdu_vo = current.txmpdu_vo + nextRandInt();
3774         out.lostmpdu_vo = current.lostmpdu_vo + nextRandInt();
3775         out.retries_vo = current.retries_vo + nextRandInt();
3776 
3777         out.on_time = current.on_time + nextRandInt();
3778         out.tx_time = current.tx_time + nextRandInt();
3779         out.rx_time = current.rx_time + nextRandInt();
3780         out.on_time_scan = current.on_time_scan + nextRandInt();
3781         out.on_time_nan_scan = current.on_time_nan_scan + nextRandInt();
3782         out.on_time_background_scan = current.on_time_background_scan + nextRandInt();
3783         out.on_time_roam_scan = current.on_time_roam_scan + nextRandInt();
3784         out.on_time_pno_scan = current.on_time_pno_scan + nextRandInt();
3785         out.on_time_hs20_scan = current.on_time_hs20_scan + nextRandInt();
3786         out.timeSliceDutyCycleInPercent =
3787                 (short) ((current.timeSliceDutyCycleInPercent + nextRandInt()) % 101);
3788         out.peerInfo = createNewPeerInfo(current.peerInfo);
3789         out.radioStats = createNewRadioStat(current.radioStats);
3790         return out;
3791     }
3792 
createNewPeerInfo(PeerInfo[] current)3793     private PeerInfo[] createNewPeerInfo(PeerInfo[] current) {
3794         if (current == null) {
3795             return null;
3796         }
3797         PeerInfo[] out = new PeerInfo[current.length];
3798         for (int i = 0; i < current.length; i++) {
3799             int numRates = 0;
3800             if (current[i].rateStats != null) {
3801                 numRates = current[i].rateStats.length;
3802             }
3803             RateStat[] rateStats = new RateStat[numRates];
3804             for (int j = 0; j < numRates; j++) {
3805                 RateStat curRate = current[i].rateStats[j];
3806                 RateStat newRate = new RateStat();
3807                 newRate.preamble = curRate.preamble;
3808                 newRate.nss = curRate.nss;
3809                 newRate.bw = curRate.bw;
3810                 newRate.rateMcsIdx = curRate.rateMcsIdx;
3811                 newRate.bitRateInKbps = curRate.bitRateInKbps;
3812                 newRate.txMpdu = curRate.txMpdu + nextRandInt();
3813                 newRate.rxMpdu = curRate.rxMpdu + nextRandInt();
3814                 newRate.mpduLost = curRate.mpduLost + nextRandInt();
3815                 newRate.retries = curRate.retries + nextRandInt();
3816                 rateStats[j] = newRate;
3817             }
3818             out[i] = new PeerInfo();
3819             out[i].rateStats = rateStats;
3820             out[i].staCount = (short) (current[i].staCount + nextRandInt() % 10);
3821             out[i].chanUtil = (short) ((current[i].chanUtil + nextRandInt()) % 100);
3822         }
3823         return out;
3824     }
3825 
createNewRadioStat(RadioStat[] current)3826     private RadioStat[] createNewRadioStat(RadioStat[] current) {
3827         if (current == null) {
3828             return null;
3829         }
3830         RadioStat[] out = new RadioStat[current.length];
3831         for (int i = 0; i < current.length; i++) {
3832             RadioStat currentRadio = current[i];
3833             RadioStat newRadio = new RadioStat();
3834             newRadio.radio_id = currentRadio.radio_id;
3835             newRadio.on_time = currentRadio.on_time + nextRandInt();
3836             newRadio.tx_time = currentRadio.tx_time + nextRandInt();
3837             newRadio.rx_time = currentRadio.rx_time + nextRandInt();
3838             newRadio.on_time_scan = currentRadio.on_time_scan + nextRandInt();
3839             newRadio.on_time_nan_scan = currentRadio.on_time_nan_scan + nextRandInt();
3840             newRadio.on_time_background_scan = currentRadio.on_time_background_scan + nextRandInt();
3841             newRadio.on_time_roam_scan = currentRadio.on_time_roam_scan + nextRandInt();
3842             newRadio.on_time_pno_scan = currentRadio.on_time_pno_scan + nextRandInt();
3843             newRadio.on_time_hs20_scan = currentRadio.on_time_hs20_scan + nextRandInt();
3844             out[i] = newRadio;
3845         }
3846         return out;
3847     }
3848 
assertWifiLinkLayerUsageHasDiff(WifiLinkLayerStats oldStats, WifiLinkLayerStats newStats)3849     private void assertWifiLinkLayerUsageHasDiff(WifiLinkLayerStats oldStats,
3850             WifiLinkLayerStats newStats) {
3851         assertEquals(newStats.timeStampInMs - oldStats.timeStampInMs,
3852                 mDecodedProto.wifiLinkLayerUsageStats.loggingDurationMs);
3853         assertEquals(newStats.on_time - oldStats.on_time,
3854                 mDecodedProto.wifiLinkLayerUsageStats.radioOnTimeMs);
3855         assertEquals(newStats.tx_time - oldStats.tx_time,
3856                 mDecodedProto.wifiLinkLayerUsageStats.radioTxTimeMs);
3857         assertEquals(newStats.rx_time - oldStats.rx_time,
3858                 mDecodedProto.wifiLinkLayerUsageStats.radioRxTimeMs);
3859         assertEquals(newStats.on_time_scan - oldStats.on_time_scan,
3860                 mDecodedProto.wifiLinkLayerUsageStats.radioScanTimeMs);
3861         assertEquals(newStats.on_time_nan_scan - oldStats.on_time_nan_scan,
3862                 mDecodedProto.wifiLinkLayerUsageStats.radioNanScanTimeMs);
3863         assertEquals(newStats.on_time_background_scan - oldStats.on_time_background_scan,
3864                 mDecodedProto.wifiLinkLayerUsageStats.radioBackgroundScanTimeMs);
3865         assertEquals(newStats.on_time_roam_scan - oldStats.on_time_roam_scan,
3866                 mDecodedProto.wifiLinkLayerUsageStats.radioRoamScanTimeMs);
3867         assertEquals(newStats.on_time_pno_scan - oldStats.on_time_pno_scan,
3868                 mDecodedProto.wifiLinkLayerUsageStats.radioPnoScanTimeMs);
3869         assertEquals(newStats.on_time_hs20_scan - oldStats.on_time_hs20_scan,
3870                 mDecodedProto.wifiLinkLayerUsageStats.radioHs20ScanTimeMs);
3871     }
3872 
assertPerRadioStatsUsageHasDiff(WifiLinkLayerStats oldStats, WifiLinkLayerStats newStats)3873     private void assertPerRadioStatsUsageHasDiff(WifiLinkLayerStats oldStats,
3874             WifiLinkLayerStats newStats) {
3875         assertEquals(oldStats.radioStats.length, newStats.radioStats.length);
3876         assertEquals(newStats.radioStats.length,
3877                 mDecodedProto.wifiLinkLayerUsageStats.radioStats.length);
3878         for (int i = 0; i < oldStats.radioStats.length; i++) {
3879             RadioStat oldRadioStats = oldStats.radioStats[i];
3880             RadioStat newRadioStats = newStats.radioStats[i];
3881             RadioStats radioStats =
3882                     mDecodedProto.wifiLinkLayerUsageStats.radioStats[i];
3883             assertEquals(oldRadioStats.radio_id, newRadioStats.radio_id);
3884             assertEquals(newRadioStats.radio_id, radioStats.radioId);
3885             assertEquals(newRadioStats.on_time - oldRadioStats.on_time,
3886                     radioStats.totalRadioOnTimeMs);
3887             assertEquals(newRadioStats.tx_time - oldRadioStats.tx_time,
3888                     radioStats.totalRadioTxTimeMs);
3889             assertEquals(newRadioStats.rx_time - oldRadioStats.rx_time,
3890                     radioStats.totalRadioRxTimeMs);
3891             assertEquals(newRadioStats.on_time_scan - oldRadioStats.on_time_scan,
3892                     radioStats.totalScanTimeMs);
3893             assertEquals(newRadioStats.on_time_nan_scan - oldRadioStats.on_time_nan_scan,
3894                     radioStats.totalNanScanTimeMs);
3895             assertEquals(newRadioStats.on_time_background_scan
3896                     - oldRadioStats.on_time_background_scan,
3897                     radioStats.totalBackgroundScanTimeMs);
3898             assertEquals(newRadioStats.on_time_roam_scan - oldRadioStats.on_time_roam_scan,
3899                     radioStats.totalRoamScanTimeMs);
3900             assertEquals(newRadioStats.on_time_pno_scan - oldRadioStats.on_time_pno_scan,
3901                     radioStats.totalPnoScanTimeMs);
3902             assertEquals(newRadioStats.on_time_hs20_scan - oldRadioStats.on_time_hs20_scan,
3903                     radioStats.totalHotspot2ScanTimeMs);
3904         }
3905     }
3906 
3907     /**
3908      * Verify that WifiMetrics is counting link layer usage correctly when given a series of
3909      * valid input.
3910      * @throws Exception
3911      */
3912     @Test
testWifiLinkLayerUsageStats()3913     public void testWifiLinkLayerUsageStats() throws Exception {
3914         WifiLinkLayerStats stat1 = nextRandomStats(createNewWifiLinkLayerStats());
3915         WifiLinkLayerStats stat2 = nextRandomStats(stat1);
3916         WifiLinkLayerStats stat3 = nextRandomStats(stat2);
3917         mWifiMetrics.incrementWifiLinkLayerUsageStats(TEST_IFACE_NAME, stat1);
3918         mWifiMetrics.incrementWifiLinkLayerUsageStats(TEST_IFACE_NAME, stat2);
3919         mWifiMetrics.incrementWifiLinkLayerUsageStats(TEST_IFACE_NAME, stat3);
3920         dumpProtoAndDeserialize();
3921 
3922         // After 2 increments, the counters should have difference between |stat1| and |stat3|
3923         assertWifiLinkLayerUsageHasDiff(stat1, stat3);
3924         assertPerRadioStatsUsageHasDiff(stat1, stat3);
3925     }
3926 
3927     /**
3928      * Verify that null input is handled and wifi link layer usage stats are not incremented.
3929      * @throws Exception
3930      */
3931     @Test
testWifiLinkLayerUsageStatsNullInput()3932     public void testWifiLinkLayerUsageStatsNullInput() throws Exception {
3933         WifiLinkLayerStats stat1 = nextRandomStats(createNewWifiLinkLayerStats());
3934         WifiLinkLayerStats stat2 = null;
3935         mWifiMetrics.incrementWifiLinkLayerUsageStats(TEST_IFACE_NAME, stat1);
3936         mWifiMetrics.incrementWifiLinkLayerUsageStats(TEST_IFACE_NAME, stat2);
3937         dumpProtoAndDeserialize();
3938 
3939         // Counter should be zero
3940         assertWifiLinkLayerUsageHasDiff(stat1, stat1);
3941         assertNotNull(mDecodedProto.wifiLinkLayerUsageStats.radioStats);
3942     }
3943 
3944     /**
3945      * Verify that when the new data appears to be bad link layer usage stats are not being
3946      * incremented and the buffered WifiLinkLayerStats get cleared.
3947      * @throws Exception
3948      */
3949     @Test
testWifiLinkLayerUsageStatsChipReset()3950     public void testWifiLinkLayerUsageStatsChipReset() throws Exception {
3951         WifiLinkLayerStats stat1 = nextRandomStats(createNewWifiLinkLayerStats());
3952         WifiLinkLayerStats stat2 = nextRandomStats(stat1);
3953         stat2.on_time = stat1.on_time - 1;
3954         WifiLinkLayerStats stat3 = nextRandomStats(stat2);
3955         WifiLinkLayerStats stat4 = nextRandomStats(stat3);
3956         mWifiMetrics.incrementWifiLinkLayerUsageStats(TEST_IFACE_NAME, stat1);
3957         mWifiMetrics.incrementWifiLinkLayerUsageStats(TEST_IFACE_NAME, stat2);
3958         mWifiMetrics.incrementWifiLinkLayerUsageStats(TEST_IFACE_NAME, stat3);
3959         mWifiMetrics.incrementWifiLinkLayerUsageStats(TEST_IFACE_NAME, stat4);
3960         dumpProtoAndDeserialize();
3961 
3962         // Should only count the difference between |stat3| and |stat4|
3963         assertWifiLinkLayerUsageHasDiff(stat3, stat4);
3964         assertPerRadioStatsUsageHasDiff(stat3, stat4);
3965     }
3966 
assertUsabilityStatsAssignment(WifiInfo info, WifiLinkLayerStats stats, WifiUsabilityStatsEntry usabilityStats)3967     private void assertUsabilityStatsAssignment(WifiInfo info, WifiLinkLayerStats stats,
3968             WifiUsabilityStatsEntry usabilityStats) {
3969         assertEquals(info.getRssi(), usabilityStats.rssi);
3970         assertEquals(info.getLinkSpeed(), usabilityStats.linkSpeedMbps);
3971         assertEquals(info.getRxLinkSpeedMbps(), usabilityStats.rxLinkSpeedMbps);
3972         assertEquals(stats.timeStampInMs, usabilityStats.timeStampMs);
3973         assertEquals(stats.txmpdu_be + stats.txmpdu_bk + stats.txmpdu_vi + stats.txmpdu_vo,
3974                 usabilityStats.totalTxSuccess);
3975         assertEquals(stats.retries_be + stats.retries_bk + stats.retries_vi + stats.retries_vo,
3976                 usabilityStats.totalTxRetries);
3977         assertEquals(stats.lostmpdu_be + stats.lostmpdu_bk + stats.lostmpdu_vi + stats.lostmpdu_vo,
3978                 usabilityStats.totalTxBad);
3979         assertEquals(stats.rxmpdu_be + stats.rxmpdu_bk + stats.rxmpdu_vi + stats.rxmpdu_vo,
3980                 usabilityStats.totalRxSuccess);
3981         assertEquals(stats.radioStats.length, usabilityStats.radioStats.length);
3982         for (int i = 0; i < stats.radioStats.length; i++) {
3983             RadioStat radio = stats.radioStats[i];
3984             RadioStats radioStats = usabilityStats.radioStats[i];
3985             assertEquals(radio.radio_id, radioStats.radioId);
3986             assertEquals(radio.on_time, radioStats.totalRadioOnTimeMs);
3987             assertEquals(radio.tx_time, radioStats.totalRadioTxTimeMs);
3988             assertEquals(radio.rx_time, radioStats.totalRadioRxTimeMs);
3989             assertEquals(radio.on_time_scan, radioStats.totalScanTimeMs);
3990             assertEquals(radio.on_time_nan_scan, radioStats.totalNanScanTimeMs);
3991             assertEquals(radio.on_time_background_scan, radioStats.totalBackgroundScanTimeMs);
3992             assertEquals(radio.on_time_roam_scan, radioStats.totalRoamScanTimeMs);
3993             assertEquals(radio.on_time_pno_scan, radioStats.totalPnoScanTimeMs);
3994             assertEquals(radio.on_time_hs20_scan, radioStats.totalHotspot2ScanTimeMs);
3995         }
3996         assertEquals(stats.on_time, usabilityStats.totalRadioOnTimeMs);
3997         assertEquals(stats.tx_time, usabilityStats.totalRadioTxTimeMs);
3998         assertEquals(stats.rx_time, usabilityStats.totalRadioRxTimeMs);
3999         assertEquals(stats.on_time_scan, usabilityStats.totalScanTimeMs);
4000         assertEquals(stats.on_time_nan_scan, usabilityStats.totalNanScanTimeMs);
4001         assertEquals(stats.on_time_background_scan, usabilityStats.totalBackgroundScanTimeMs);
4002         assertEquals(stats.on_time_roam_scan, usabilityStats.totalRoamScanTimeMs);
4003         assertEquals(stats.on_time_pno_scan, usabilityStats.totalPnoScanTimeMs);
4004         assertEquals(stats.on_time_hs20_scan, usabilityStats.totalHotspot2ScanTimeMs);
4005         assertEquals(stats.beacon_rx, usabilityStats.totalBeaconRx);
4006         assertEquals(stats.timeSliceDutyCycleInPercent, usabilityStats.timeSliceDutyCycleInPercent);
4007         assertEquals(stats.contentionTimeMinBeInUsec,
4008                 usabilityStats.contentionTimeStats[0].contentionTimeMinMicros);
4009         assertEquals(stats.contentionTimeMaxBeInUsec,
4010                 usabilityStats.contentionTimeStats[0].contentionTimeMaxMicros);
4011         assertEquals(stats.contentionTimeAvgBeInUsec,
4012                 usabilityStats.contentionTimeStats[0].contentionTimeAvgMicros);
4013         assertEquals(stats.contentionNumSamplesBe,
4014                 usabilityStats.contentionTimeStats[0].contentionNumSamples);
4015         assertEquals(stats.contentionTimeMinBkInUsec,
4016                 usabilityStats.contentionTimeStats[1].contentionTimeMinMicros);
4017         assertEquals(stats.contentionTimeMaxBkInUsec,
4018                 usabilityStats.contentionTimeStats[1].contentionTimeMaxMicros);
4019         assertEquals(stats.contentionTimeAvgBkInUsec,
4020                 usabilityStats.contentionTimeStats[1].contentionTimeAvgMicros);
4021         assertEquals(stats.contentionNumSamplesBk,
4022                 usabilityStats.contentionTimeStats[1].contentionNumSamples);
4023         assertEquals(stats.contentionTimeMinViInUsec,
4024                 usabilityStats.contentionTimeStats[2].contentionTimeMinMicros);
4025         assertEquals(stats.contentionTimeMaxViInUsec,
4026                 usabilityStats.contentionTimeStats[2].contentionTimeMaxMicros);
4027         assertEquals(stats.contentionTimeAvgViInUsec,
4028                 usabilityStats.contentionTimeStats[2].contentionTimeAvgMicros);
4029         assertEquals(stats.contentionNumSamplesVi,
4030                 usabilityStats.contentionTimeStats[2].contentionNumSamples);
4031         assertEquals(stats.contentionTimeMinVoInUsec,
4032                 usabilityStats.contentionTimeStats[3].contentionTimeMinMicros);
4033         assertEquals(stats.contentionTimeMaxVoInUsec,
4034                 usabilityStats.contentionTimeStats[3].contentionTimeMaxMicros);
4035         assertEquals(stats.contentionTimeAvgVoInUsec,
4036                 usabilityStats.contentionTimeStats[3].contentionTimeAvgMicros);
4037         assertEquals(stats.contentionNumSamplesVo,
4038                 usabilityStats.contentionTimeStats[3].contentionNumSamples);
4039         for (int i = 0; i < stats.peerInfo.length; i++) {
4040             PeerInfo curPeer = stats.peerInfo[i];
4041             assertEquals(curPeer.staCount, usabilityStats.staCount);
4042             assertEquals(curPeer.chanUtil, usabilityStats.channelUtilization);
4043             for (int j = 0; j < curPeer.rateStats.length; j++) {
4044                 RateStat rate = curPeer.rateStats[j];
4045                 RateStats usabilityRate = usabilityStats.rateStats[j];
4046                 assertEquals(rate.preamble, usabilityRate.preamble);
4047                 assertEquals(rate.nss, usabilityRate.nss);
4048                 assertEquals(rate.bw, usabilityRate.bw);
4049                 assertEquals(rate.rateMcsIdx, usabilityRate.rateMcsIdx);
4050                 assertEquals(rate.bitRateInKbps, usabilityRate.bitRateInKbps);
4051                 assertEquals(rate.txMpdu, usabilityRate.txMpdu);
4052                 assertEquals(rate.rxMpdu, usabilityRate.rxMpdu);
4053                 assertEquals(rate.mpduLost, usabilityRate.mpduLost);
4054                 assertEquals(rate.retries, usabilityRate.retries);
4055             }
4056         }
4057     }
4058 
4059     // Simulate adding a LABEL_GOOD WifiUsabilityStats
addGoodWifiUsabilityStats(WifiLinkLayerStats start)4060     private WifiLinkLayerStats addGoodWifiUsabilityStats(WifiLinkLayerStats start) {
4061         WifiInfo info = mock(WifiInfo.class);
4062         when(info.getRssi()).thenReturn(nextRandInt());
4063         when(info.getLinkSpeed()).thenReturn(nextRandInt());
4064         WifiLinkLayerStats stats = start;
4065         for (int i = 0; i < WifiMetrics.NUM_WIFI_USABILITY_STATS_ENTRIES_PER_WIFI_GOOD; i++) {
4066             mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats);
4067             stats = nextRandomStats(stats);
4068         }
4069         return stats;
4070     }
4071 
4072     // Simulate adding a LABEL_BAD WifiUsabilityStats
addBadWifiUsabilityStats(WifiLinkLayerStats start)4073     private WifiLinkLayerStats addBadWifiUsabilityStats(WifiLinkLayerStats start) {
4074         WifiInfo info = mock(WifiInfo.class);
4075         when(info.getRssi()).thenReturn(nextRandInt());
4076         when(info.getLinkSpeed()).thenReturn(nextRandInt());
4077         WifiLinkLayerStats stats1 = start;
4078         WifiLinkLayerStats stats2 = nextRandomStats(stats1);
4079         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats1);
4080         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats2);
4081         mWifiMetrics.addToWifiUsabilityStatsList(TEST_IFACE_NAME, WifiUsabilityStats.LABEL_BAD,
4082                 WifiUsabilityStats.TYPE_DATA_STALL_BAD_TX, -1);
4083         return nextRandomStats(stats2);
4084     }
4085 
4086     /**
4087      * Verify that updateWifiUsabilityStatsEntries correctly converts the inputs into
4088      * a WifiUsabilityStatsEntry Object and then stores it.
4089      *
4090      * Verify that the converted metrics proto contains pairs of WifiUsabilityStats with
4091      * LABEL_GOOD and LABEL_BAD
4092      * @throws Exception
4093      */
4094     @Test
testUpdateWifiUsabilityStatsEntries()4095     public void testUpdateWifiUsabilityStatsEntries() throws Exception {
4096         WifiInfo info = mock(WifiInfo.class);
4097         when(info.getRssi()).thenReturn(nextRandInt());
4098         when(info.getLinkSpeed()).thenReturn(nextRandInt());
4099         when(info.getRxLinkSpeedMbps()).thenReturn(nextRandInt());
4100         when(info.getBSSID()).thenReturn("Wifi");
4101         when(info.getFrequency()).thenReturn(5745);
4102         when(mWifiDataStall.isCellularDataAvailable()).thenReturn(true);
4103         when(mWifiDataStall.isThroughputSufficient()).thenReturn(false);
4104         when(mWifiChannelUtilization.getUtilizationRatio(anyInt())).thenReturn(150);
4105         when(mWifiSettingsStore.isWifiScoringEnabled()).thenReturn(true);
4106 
4107         WifiLinkLayerStats stats1 = nextRandomStats(createNewWifiLinkLayerStats());
4108         WifiLinkLayerStats stats2 = nextRandomStats(stats1);
4109         mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, 60);
4110         mWifiMetrics.incrementWifiUsabilityScoreCount(TEST_IFACE_NAME, 2, 55, 15);
4111         mWifiMetrics.logLinkProbeSuccess(
4112                 TEST_IFACE_NAME, nextRandInt(), nextRandInt(), nextRandInt(), 12);
4113         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats1);
4114         mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, 58);
4115         mWifiMetrics.incrementWifiUsabilityScoreCount(TEST_IFACE_NAME, 3, 56, 15);
4116         mWifiMetrics.logLinkProbeFailure(TEST_IFACE_NAME, nextRandInt(), nextRandInt(),
4117                 nextRandInt(), nextRandInt());
4118         mWifiMetrics.enterDeviceMobilityState(DEVICE_MOBILITY_STATE_HIGH_MVMT);
4119 
4120         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats2);
4121         mWifiMetrics.addToWifiUsabilityStatsList(TEST_IFACE_NAME, WifiUsabilityStats.LABEL_BAD,
4122                 WifiUsabilityStats.TYPE_DATA_STALL_BAD_TX, -1);
4123 
4124         // Add 2 LABEL_GOOD but only 1 should remain in the converted proto
4125         WifiLinkLayerStats statsGood = addGoodWifiUsabilityStats(nextRandomStats(stats2));
4126         statsGood.timeStampInMs += WifiMetrics.MIN_WIFI_GOOD_USABILITY_STATS_PERIOD_MS;
4127         addGoodWifiUsabilityStats(statsGood);
4128 
4129         dumpProtoAndDeserialize();
4130         assertEquals(2, mDecodedProto.wifiUsabilityStatsList.length);
4131         assertEquals(WifiUsabilityStats.LABEL_GOOD, mDecodedProto.wifiUsabilityStatsList[0].label);
4132         assertEquals(WifiUsabilityStats.LABEL_BAD, mDecodedProto.wifiUsabilityStatsList[1].label);
4133         assertUsabilityStatsAssignment(info, stats1,
4134                 mDecodedProto.wifiUsabilityStatsList[1].stats[0]);
4135         assertUsabilityStatsAssignment(info, stats2,
4136                 mDecodedProto.wifiUsabilityStatsList[1].stats[1]);
4137 
4138         assertEquals(2, mDecodedProto.wifiUsabilityStatsList[1].stats[0].seqNumToFramework);
4139         assertEquals(3, mDecodedProto.wifiUsabilityStatsList[1].stats[1].seqNumToFramework);
4140         assertEquals(0, mDecodedProto.wifiUsabilityStatsList[1].stats[0].seqNumInsideFramework);
4141         assertEquals(1, mDecodedProto.wifiUsabilityStatsList[1].stats[1].seqNumInsideFramework);
4142         assertEquals(60, mDecodedProto.wifiUsabilityStatsList[1].stats[0].wifiScore);
4143         assertEquals(58, mDecodedProto.wifiUsabilityStatsList[1].stats[1].wifiScore);
4144         assertEquals(55, mDecodedProto.wifiUsabilityStatsList[1].stats[0].wifiUsabilityScore);
4145         assertEquals(56, mDecodedProto.wifiUsabilityStatsList[1].stats[1].wifiUsabilityScore);
4146         assertEquals(15, mDecodedProto.wifiUsabilityStatsList[1].stats[0].predictionHorizonSec);
4147         assertEquals(true, mDecodedProto.wifiUsabilityStatsList[1].stats[0].isSameBssidAndFreq);
4148         assertEquals(android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS,
4149                 mDecodedProto.wifiUsabilityStatsList[1].stats[0].probeStatusSinceLastUpdate);
4150         assertEquals(android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE,
4151                 mDecodedProto.wifiUsabilityStatsList[1].stats[1].probeStatusSinceLastUpdate);
4152         assertEquals(android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE,
4153                 mDecodedProto.wifiUsabilityStatsList[0].stats[0].probeStatusSinceLastUpdate);
4154         assertEquals(12,
4155                 mDecodedProto.wifiUsabilityStatsList[1].stats[0].probeElapsedTimeSinceLastUpdateMs);
4156         assertEquals(Integer.MAX_VALUE, mDecodedProto.wifiUsabilityStatsList[1]
4157                 .stats[1].probeElapsedTimeSinceLastUpdateMs);
4158         assertEquals(-1, mDecodedProto.wifiUsabilityStatsList[0]
4159                 .stats[0].probeElapsedTimeSinceLastUpdateMs);
4160         assertEquals(DEVICE_MOBILITY_STATE_HIGH_MVMT, mDecodedProto.wifiUsabilityStatsList[1]
4161                 .stats[mDecodedProto.wifiUsabilityStatsList[1].stats.length - 1]
4162                 .deviceMobilityState);
4163         assertEquals(true, mDecodedProto.wifiUsabilityStatsList[0].stats[0].isWifiScoringEnabled);
4164         assertEquals(true,
4165                 mDecodedProto.wifiUsabilityStatsList[1].stats[0].isCellularDataAvailable);
4166         assertEquals(false,
4167                 mDecodedProto.wifiUsabilityStatsList[1].stats[1].isThroughputSufficient);
4168         assertEquals(150,
4169                 mDecodedProto.wifiUsabilityStatsList[0].stats[0].channelUtilizationRatio);
4170     }
4171 
createNewWifiLinkLayerStats()4172     private WifiLinkLayerStats createNewWifiLinkLayerStats() {
4173         WifiLinkLayerStats stats = new WifiLinkLayerStats();
4174         RateStat[] rateStats = new RateStat[1];
4175         rateStats[0] = new RateStat();
4176         rateStats[0].preamble = 1;
4177         rateStats[0].nss = 1;
4178         rateStats[0].bw = 2;
4179         rateStats[0].rateMcsIdx = 5;
4180         rateStats[0].bitRateInKbps = 2000;
4181         PeerInfo[] peerInfo = new PeerInfo[1];
4182         peerInfo[0] = new PeerInfo();
4183         peerInfo[0].rateStats = rateStats;
4184         stats.peerInfo = peerInfo;
4185         RadioStat[] radioStats = new RadioStat[2];
4186         for (int i = 0; i < 2; i++) {
4187             RadioStat radio = new RadioStat();
4188             radio.radio_id = i;
4189             radioStats[i] = radio;
4190         }
4191         stats.radioStats = radioStats;
4192         return stats;
4193     }
4194 
4195     /**
4196      * Verify that when there are no WifiUsability events the generated proto also contains no
4197      * such information.
4198      * @throws Exception
4199      */
4200     @Test
testWifiUsabilityStatsZeroEvents()4201     public void testWifiUsabilityStatsZeroEvents() throws Exception {
4202         dumpProtoAndDeserialize();
4203         assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length);
4204     }
4205 
4206     /**
4207      * Verify that we discard a WifiUsabilityStats with LABEL_GOOD if there is no corresponding
4208      * LABEL_BAD
4209      * @throws Exception
4210      */
4211     @Test
testWifiUsabilityStatsIgnoreSingleLabelGood()4212     public void testWifiUsabilityStatsIgnoreSingleLabelGood() throws Exception {
4213         addGoodWifiUsabilityStats(new WifiLinkLayerStats());
4214         dumpProtoAndDeserialize();
4215         assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length);
4216     }
4217 
4218     /**
4219      * Verify that we discard a WifiUsabilityStats with LABEL_BAD if there is no corresponding
4220      * LABEL_GOOD
4221      * @throws Exception
4222      */
4223     @Test
testWifiUsabilityStatsIgnoreSingleLabelBad()4224     public void testWifiUsabilityStatsIgnoreSingleLabelBad() throws Exception {
4225         addBadWifiUsabilityStats(new WifiLinkLayerStats());
4226         dumpProtoAndDeserialize();
4227         assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length);
4228     }
4229 
4230     /**
4231      * Verify that the buffer for WifiUsabilityStats does not exceed the max length.
4232      * Do this by trying to add more WifiUsabilityStats than the max length and then
4233      * verifying that the decoded proto's length does not exceed the max length.
4234      *
4235      * Also verify that the length for the list of WifiUsabilityStatsEntry is capped.
4236      * @throws Exception
4237      */
4238     @Test
testWifiUsabilityStatsBufferSizeIsCapped()4239     public void testWifiUsabilityStatsBufferSizeIsCapped() throws Exception {
4240         // simulate adding LABEL_GOOD WifiUsabilityStats 1 time over the max limit
4241         WifiLinkLayerStats stats = new WifiLinkLayerStats();
4242         for (int j = 0; j < WifiMetrics.MAX_WIFI_USABILITY_STATS_LIST_SIZE_PER_TYPE + 1; j++) {
4243             stats = addGoodWifiUsabilityStats(stats);
4244             stats = addBadWifiUsabilityStats(stats);
4245             stats.timeStampInMs += WifiMetrics.MIN_WIFI_GOOD_USABILITY_STATS_PERIOD_MS;
4246         }
4247         dumpProtoAndDeserialize();
4248         assertEquals(2 * WifiMetrics.MAX_WIFI_USABILITY_STATS_PER_TYPE_TO_UPLOAD,
4249                 mDecodedProto.wifiUsabilityStatsList.length);
4250         for (int i = 0; i < WifiMetrics.MAX_WIFI_USABILITY_STATS_PER_TYPE_TO_UPLOAD; i++) {
4251             assertEquals(WifiMetrics.MAX_WIFI_USABILITY_STATS_ENTRIES_LIST_SIZE,
4252                     mDecodedProto.wifiUsabilityStatsList[2 * i].stats.length);
4253             assertEquals(2, mDecodedProto.wifiUsabilityStatsList[2 * i + 1].stats.length);
4254         }
4255     }
4256 
4257     /**
4258      * Verify that LABEL_GOOD stats are not generated more frequently than
4259      * |MIN_WIFI_GOOD_USABILITY_STATS_PERIOD_MS|
4260      * @throws Exception
4261      */
4262     @Test
testWifiUsabilityStatsLabelGoodHasMinimumPeriod()4263     public void testWifiUsabilityStatsLabelGoodHasMinimumPeriod() throws Exception {
4264         // simulate adding LABEL_GOOD WifiUsabilityStats 1 time over the max limit
4265         WifiLinkLayerStats stats = new WifiLinkLayerStats();
4266         for (int j = 0; j < 2; j++) {
4267             stats = addGoodWifiUsabilityStats(stats);
4268             stats = addBadWifiUsabilityStats(stats);
4269         }
4270         dumpProtoAndDeserialize();
4271         assertEquals(2, mDecodedProto.wifiUsabilityStatsList.length);
4272     }
4273 
4274     /**
4275      * Verify that LABEL_BAD stats are not generated more frequently than |MIN_DATA_STALL_WAIT_MS|
4276      * @throws Exception
4277      */
4278     @Test
testWifiUsabilityStatsLabelBadNotGeneratedGapLessThanMinimum()4279     public void testWifiUsabilityStatsLabelBadNotGeneratedGapLessThanMinimum() throws Exception {
4280         // simulate adding two LABEL_GOOD WifiUsabilityStats
4281         WifiInfo info = mock(WifiInfo.class);
4282         when(info.getRssi()).thenReturn(nextRandInt());
4283         when(info.getLinkSpeed()).thenReturn(nextRandInt());
4284         WifiLinkLayerStats stats1 = new WifiLinkLayerStats();
4285         WifiLinkLayerStats stats2 = new WifiLinkLayerStats();
4286         stats1 = addGoodWifiUsabilityStats(stats1);
4287         stats2.timeStampInMs = stats1.timeStampInMs
4288                 + WifiMetrics.MIN_WIFI_GOOD_USABILITY_STATS_PERIOD_MS;
4289         addGoodWifiUsabilityStats(stats2);
4290 
4291         WifiLinkLayerStats stats3 = new WifiLinkLayerStats();
4292         WifiLinkLayerStats stats4 = new WifiLinkLayerStats();
4293         for (int i = 0; i < WifiMetrics.MAX_WIFI_USABILITY_STATS_ENTRIES_LIST_SIZE - 1; i++) {
4294             mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats3);
4295             stats3 = nextRandomStats(stats3);
4296         }
4297         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats3);
4298         mWifiMetrics.addToWifiUsabilityStatsList(TEST_IFACE_NAME, WifiUsabilityStats.LABEL_BAD,
4299                 WifiUsabilityStats.TYPE_DATA_STALL_BAD_TX, -1);
4300         for (int i = 0; i < WifiMetrics.MAX_WIFI_USABILITY_STATS_ENTRIES_LIST_SIZE - 1; i++) {
4301             mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats4);
4302             stats4 = nextRandomStats(stats4);
4303         }
4304         stats4.timeStampInMs = stats3.timeStampInMs - 1 + WifiMetrics.MIN_DATA_STALL_WAIT_MS;
4305         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats4);
4306         mWifiMetrics.addToWifiUsabilityStatsList(TEST_IFACE_NAME, WifiUsabilityStats.LABEL_BAD,
4307                 WifiUsabilityStats.TYPE_DATA_STALL_BAD_TX, -1);
4308         dumpProtoAndDeserialize();
4309         assertEquals(2, mDecodedProto.wifiUsabilityStatsList.length);
4310     }
4311 
4312     /**
4313      * Verify that LABEL_BAD stats are generated if timestamp gap is larger than
4314      * |MIN_DATA_STALL_WAIT_MS|
4315      * @throws Exception
4316      */
4317     @Test
testWifiUsabilityStatsLabelBadGeneratedGapLargerThanMinimum()4318     public void testWifiUsabilityStatsLabelBadGeneratedGapLargerThanMinimum() throws Exception {
4319         // simulate adding two LABEL_GOOD WifiUsabilityStats
4320         WifiInfo info = mock(WifiInfo.class);
4321         when(info.getRssi()).thenReturn(nextRandInt());
4322         when(info.getLinkSpeed()).thenReturn(nextRandInt());
4323         WifiLinkLayerStats stats1 = new WifiLinkLayerStats();
4324         WifiLinkLayerStats stats2 = new WifiLinkLayerStats();
4325         stats1 = addGoodWifiUsabilityStats(stats1);
4326         stats2.timeStampInMs = stats1.timeStampInMs
4327                 + WifiMetrics.MIN_WIFI_GOOD_USABILITY_STATS_PERIOD_MS;
4328         addGoodWifiUsabilityStats(stats2);
4329 
4330         WifiLinkLayerStats stats3 = new WifiLinkLayerStats();
4331         WifiLinkLayerStats stats4 = new WifiLinkLayerStats();
4332         for (int i = 0; i < WifiMetrics.MAX_WIFI_USABILITY_STATS_ENTRIES_LIST_SIZE - 1; i++) {
4333             mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats3);
4334             stats3 = nextRandomStats(stats3);
4335         }
4336         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats3);
4337         mWifiMetrics.addToWifiUsabilityStatsList(TEST_IFACE_NAME, WifiUsabilityStats.LABEL_BAD,
4338                 WifiUsabilityStats.TYPE_DATA_STALL_BAD_TX, -1);
4339         for (int i = 0; i < WifiMetrics.MAX_WIFI_USABILITY_STATS_ENTRIES_LIST_SIZE - 1; i++) {
4340             mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats4);
4341             stats4 = nextRandomStats(stats4);
4342         }
4343         stats4.timeStampInMs = stats3.timeStampInMs + 1 + WifiMetrics.MIN_DATA_STALL_WAIT_MS;
4344         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats4);
4345         mWifiMetrics.addToWifiUsabilityStatsList(TEST_IFACE_NAME, WifiUsabilityStats.LABEL_BAD,
4346                 WifiUsabilityStats.TYPE_DATA_STALL_BAD_TX, -1);
4347         dumpProtoAndDeserialize();
4348         assertEquals(4, mDecodedProto.wifiUsabilityStatsList.length);
4349     }
4350 
4351     /**
4352      * Tests device mobility state metrics as states are changed.
4353      */
4354     @Test
testDeviceMobilityStateMetrics_changeState()4355     public void testDeviceMobilityStateMetrics_changeState() throws Exception {
4356         // timeMs is initialized to 0 by the setUp() method
4357         long timeMs = 1000;
4358         when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs);
4359         mWifiMetrics.enterDeviceMobilityState(DEVICE_MOBILITY_STATE_STATIONARY);
4360 
4361         timeMs += 2000;
4362         when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs);
4363         mWifiMetrics.enterDeviceMobilityState(DEVICE_MOBILITY_STATE_LOW_MVMT);
4364 
4365         dumpProtoAndDeserialize();
4366 
4367         DeviceMobilityStatePnoScanStats[] expected = {
4368                 buildDeviceMobilityStatePnoScanStats(DEVICE_MOBILITY_STATE_UNKNOWN, 1, 1000, 0),
4369                 buildDeviceMobilityStatePnoScanStats(DEVICE_MOBILITY_STATE_STATIONARY, 1, 2000, 0),
4370                 buildDeviceMobilityStatePnoScanStats(DEVICE_MOBILITY_STATE_LOW_MVMT, 1, 0, 0)
4371         };
4372 
4373         assertDeviceMobilityStatePnoScanStatsEqual(
4374                 expected, mDecodedProto.mobilityStatePnoStatsList);
4375     }
4376 
4377     /**
4378      * Tests device mobility state metrics as PNO scans are started and stopped.
4379      */
4380     @Test
testDeviceMobilityStateMetrics_startStopPnoScans()4381     public void testDeviceMobilityStateMetrics_startStopPnoScans() throws Exception {
4382         long timeMs = 1000;
4383         when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs);
4384         mWifiMetrics.logPnoScanStart();
4385 
4386         timeMs += 2000;
4387         when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs);
4388         mWifiMetrics.logPnoScanStop();
4389         mWifiMetrics.enterDeviceMobilityState(DEVICE_MOBILITY_STATE_STATIONARY);
4390         mWifiMetrics.logPnoScanStart();
4391 
4392         timeMs += 4000;
4393         when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs);
4394         mWifiMetrics.logPnoScanStop();
4395 
4396         timeMs += 8000;
4397         when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs);
4398         mWifiMetrics.enterDeviceMobilityState(DEVICE_MOBILITY_STATE_HIGH_MVMT);
4399 
4400         dumpProtoAndDeserialize();
4401 
4402         DeviceMobilityStatePnoScanStats[] expected = {
4403                 buildDeviceMobilityStatePnoScanStats(DEVICE_MOBILITY_STATE_UNKNOWN,
4404                         1, 1000 + 2000, 2000),
4405                 buildDeviceMobilityStatePnoScanStats(DEVICE_MOBILITY_STATE_STATIONARY,
4406                         1, 4000 + 8000, 4000),
4407                 buildDeviceMobilityStatePnoScanStats(DEVICE_MOBILITY_STATE_HIGH_MVMT, 1, 0, 0)
4408         };
4409 
4410         assertDeviceMobilityStatePnoScanStatsEqual(
4411                 expected, mDecodedProto.mobilityStatePnoStatsList);
4412     }
4413 
4414     /**
4415      * Tests that the initial state is set up correctly.
4416      */
4417     @Test
testDeviceMobilityStateMetrics_initialState()4418     public void testDeviceMobilityStateMetrics_initialState() throws Exception {
4419         dumpProtoAndDeserialize();
4420 
4421         DeviceMobilityStatePnoScanStats[] expected = {
4422                 buildDeviceMobilityStatePnoScanStats(DEVICE_MOBILITY_STATE_UNKNOWN, 1, 0, 0)
4423         };
4424 
4425         assertDeviceMobilityStatePnoScanStatsEqual(
4426                 expected, mDecodedProto.mobilityStatePnoStatsList);
4427     }
4428 
4429     /**
4430      * Tests that logPnoScanStart() updates the total duration in addition to the PNO duration.
4431      */
4432     @Test
testDeviceMobilityStateMetrics_startPnoScansUpdatesTotalDuration()4433     public void testDeviceMobilityStateMetrics_startPnoScansUpdatesTotalDuration()
4434             throws Exception {
4435         long timeMs = 1000;
4436         when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs);
4437         mWifiMetrics.logPnoScanStart();
4438 
4439         dumpProtoAndDeserialize();
4440 
4441         DeviceMobilityStatePnoScanStats[] expected = {
4442                 buildDeviceMobilityStatePnoScanStats(DEVICE_MOBILITY_STATE_UNKNOWN, 1, 1000, 0)
4443         };
4444 
4445         assertDeviceMobilityStatePnoScanStatsEqual(
4446                 expected, mDecodedProto.mobilityStatePnoStatsList);
4447     }
4448 
4449     /**
4450      * Tests that logPnoScanStop() updates the total duration in addition to the PNO duration.
4451      */
4452     @Test
testDeviceMobilityStateMetrics_stopPnoScansUpdatesTotalDuration()4453     public void testDeviceMobilityStateMetrics_stopPnoScansUpdatesTotalDuration()
4454             throws Exception {
4455         long timeMs = 1000;
4456         when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs);
4457         mWifiMetrics.logPnoScanStart();
4458 
4459         timeMs += 2000;
4460         when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs);
4461         mWifiMetrics.logPnoScanStop();
4462 
4463         dumpProtoAndDeserialize();
4464 
4465         DeviceMobilityStatePnoScanStats[] expected = {
4466                 buildDeviceMobilityStatePnoScanStats(DEVICE_MOBILITY_STATE_UNKNOWN,
4467                         1, 1000 + 2000, 2000)
4468         };
4469 
4470         assertDeviceMobilityStatePnoScanStatsEqual(
4471                 expected, mDecodedProto.mobilityStatePnoStatsList);
4472     }
4473 
4474     /**
4475      * Verify that clients should be notified of activity in case Wifi stats get updated.
4476      */
4477     @Test
testClientNotification()4478     public void testClientNotification() throws RemoteException {
4479         // Register Client for verification.
4480         ArgumentCaptor<android.net.wifi.WifiUsabilityStatsEntry> usabilityStats =
4481                 ArgumentCaptor.forClass(android.net.wifi.WifiUsabilityStatsEntry.class);
4482         mWifiMetrics.addOnWifiUsabilityListener(mOnWifiUsabilityStatsListener);
4483         WifiInfo info = mock(WifiInfo.class);
4484         when(info.getRssi()).thenReturn(nextRandInt());
4485         when(info.getLinkSpeed()).thenReturn(nextRandInt());
4486 
4487         WifiLinkLayerStats linkLayerStats = nextRandomStats(new WifiLinkLayerStats());
4488         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, linkLayerStats);
4489 
4490         // Client should get the stats.
4491         verify(mOnWifiUsabilityStatsListener).onWifiUsabilityStats(anyInt(), anyBoolean(),
4492                 usabilityStats.capture());
4493         assertEquals(usabilityStats.getValue().getTotalRadioOnTimeMillis(), linkLayerStats.on_time);
4494         assertEquals(usabilityStats.getValue().getTotalTxBad(), linkLayerStats.lostmpdu_be
4495                 + linkLayerStats.lostmpdu_bk + linkLayerStats.lostmpdu_vi
4496                 + linkLayerStats.lostmpdu_vo);
4497         assertEquals(usabilityStats.getValue().getTimeStampMillis(), linkLayerStats.timeStampInMs);
4498         assertEquals(usabilityStats.getValue().getTotalRoamScanTimeMillis(),
4499                 linkLayerStats.on_time_roam_scan);
4500     }
4501 
4502     /**
4503      * Verify that remove client should be handled
4504      */
4505     @Test
testRemoveClient()4506     public void testRemoveClient() throws RemoteException {
4507         // Register Client for verification.
4508         mWifiMetrics.addOnWifiUsabilityListener(mOnWifiUsabilityStatsListener);
4509         mWifiMetrics.removeOnWifiUsabilityListener(mOnWifiUsabilityStatsListener);
4510         verify(mAppBinder).unlinkToDeath(any(), anyInt());
4511 
4512         WifiInfo info = mock(WifiInfo.class);
4513         when(info.getRssi()).thenReturn(nextRandInt());
4514         when(info.getLinkSpeed()).thenReturn(nextRandInt());
4515         WifiLinkLayerStats linkLayerStats = nextRandomStats(new WifiLinkLayerStats());
4516         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, linkLayerStats);
4517 
4518         verify(mOnWifiUsabilityStatsListener, never()).onWifiUsabilityStats(anyInt(),
4519                 anyBoolean(), any());
4520     }
4521 
4522     /**
4523      * Verify that WifiMetrics adds for death notification on adding client.
4524      */
4525     @Test
testAddsForBinderDeathOnAddClient()4526     public void testAddsForBinderDeathOnAddClient() throws Exception {
4527         mWifiMetrics.addOnWifiUsabilityListener(mOnWifiUsabilityStatsListener);
4528         verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
4529     }
4530 
4531     /**
4532      * Verify that client fails to get message when listener add failed.
4533      */
4534     @Test
testAddsListenerFailureOnLinkToDeath()4535     public void testAddsListenerFailureOnLinkToDeath() throws Exception {
4536         doThrow(new RemoteException())
4537                 .when(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
4538         mWifiMetrics.addOnWifiUsabilityListener(mOnWifiUsabilityStatsListener);
4539         verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
4540 
4541         WifiInfo info = mock(WifiInfo.class);
4542         when(info.getRssi()).thenReturn(nextRandInt());
4543         when(info.getLinkSpeed()).thenReturn(nextRandInt());
4544         WifiLinkLayerStats linkLayerStats = nextRandomStats(new WifiLinkLayerStats());
4545         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, linkLayerStats);
4546 
4547         // Client should not get any message listener add failed.
4548         verify(mOnWifiUsabilityStatsListener, never()).onWifiUsabilityStats(anyInt(),
4549                 anyBoolean(), any());
4550     }
4551 
4552     /**
4553      * Verify that the label and the triggerType of Wifi usability stats are saved correctly
4554      * during firmware alert is triggered.
4555      * @throws Exception
4556      */
4557     @Test
verifyFirmwareAlertUpdatesWifiUsabilityMetrics()4558     public void verifyFirmwareAlertUpdatesWifiUsabilityMetrics() throws Exception {
4559         WifiInfo info = mock(WifiInfo.class);
4560         when(info.getRssi()).thenReturn(nextRandInt());
4561         when(info.getLinkSpeed()).thenReturn(nextRandInt());
4562         long eventTimeMs = nextRandInt();
4563         when(mClock.getElapsedSinceBootMillis()).thenReturn(eventTimeMs);
4564         WifiLinkLayerStats stats1 = nextRandomStats(new WifiLinkLayerStats());
4565         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats1);
4566 
4567         // Add 1 LABEL_GOOD
4568         WifiLinkLayerStats statsGood = addGoodWifiUsabilityStats(nextRandomStats(stats1));
4569         // Firmware alert occurs
4570         mWifiMetrics.logFirmwareAlert(TEST_IFACE_NAME, 2);
4571 
4572         dumpProtoAndDeserialize();
4573         assertEquals(2, mDecodedProto.wifiUsabilityStatsList.length);
4574 
4575         WifiUsabilityStats[] statsList = mDecodedProto.wifiUsabilityStatsList;
4576         assertEquals(WifiUsabilityStats.LABEL_GOOD, statsList[0].label);
4577         assertEquals(WifiUsabilityStats.LABEL_BAD, statsList[1].label);
4578         assertEquals(WifiIsUnusableEvent.TYPE_FIRMWARE_ALERT, statsList[1].triggerType);
4579         assertEquals(eventTimeMs, statsList[1].timeStampMs);
4580         assertEquals(2, statsList[1].firmwareAlertCode);
4581     }
4582 
4583     /**
4584      * Verify that the label and the triggerType of Wifi usability stats are saved correctly
4585      * during Wifi data stall is triggered.
4586      * @throws Exception
4587      */
4588     @Test
verifyWifiDataStallUpdatesWifiUsabilityMetrics()4589     public void verifyWifiDataStallUpdatesWifiUsabilityMetrics() throws Exception {
4590         WifiInfo info = mock(WifiInfo.class);
4591         when(info.getRssi()).thenReturn(nextRandInt());
4592         when(info.getLinkSpeed()).thenReturn(nextRandInt());
4593         long eventTimeMs = nextRandInt();
4594         when(mClock.getElapsedSinceBootMillis()).thenReturn(eventTimeMs);
4595         WifiLinkLayerStats stats1 = nextRandomStats(new WifiLinkLayerStats());
4596         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats1);
4597 
4598         // Add 1 LABEL_GOOD
4599         WifiLinkLayerStats statsGood = addGoodWifiUsabilityStats(nextRandomStats(stats1));
4600         // Wifi data stall occurs
4601         mWifiMetrics.addToWifiUsabilityStatsList(TEST_IFACE_NAME, WifiUsabilityStats.LABEL_BAD,
4602                 WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX, -1);
4603 
4604         dumpProtoAndDeserialize();
4605         assertEquals(2, mDecodedProto.wifiUsabilityStatsList.length);
4606         WifiUsabilityStats[] statsList = mDecodedProto.wifiUsabilityStatsList;
4607         assertEquals(WifiUsabilityStats.LABEL_BAD, statsList[1].label);
4608         assertEquals(WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX, statsList[1].triggerType);
4609         assertEquals(-1, statsList[1].firmwareAlertCode);
4610         assertEquals(eventTimeMs, statsList[1].timeStampMs);
4611     }
4612 
4613     /**
4614      * Test the generation of 'WifiConfigStoreIODuration' read histograms.
4615      */
4616     @Test
testWifiConfigStoreReadDurationsHistogramGeneration()4617     public void testWifiConfigStoreReadDurationsHistogramGeneration() throws Exception {
4618         mWifiMetrics.noteWifiConfigStoreReadDuration(10);
4619         mWifiMetrics.noteWifiConfigStoreReadDuration(20);
4620         mWifiMetrics.noteWifiConfigStoreReadDuration(100);
4621         mWifiMetrics.noteWifiConfigStoreReadDuration(90);
4622         mWifiMetrics.noteWifiConfigStoreReadDuration(130);
4623         mWifiMetrics.noteWifiConfigStoreReadDuration(250);
4624         mWifiMetrics.noteWifiConfigStoreReadDuration(600);
4625 
4626         dumpProtoAndDeserialize();
4627 
4628         assertEquals(5, mDecodedProto.wifiConfigStoreIo.readDurations.length);
4629         assertEquals(0, mDecodedProto.wifiConfigStoreIo.writeDurations.length);
4630 
4631         assertEquals(Integer.MIN_VALUE,
4632                 mDecodedProto.wifiConfigStoreIo.readDurations[0].rangeStartMs);
4633         assertEquals(50, mDecodedProto.wifiConfigStoreIo.readDurations[0].rangeEndMs);
4634         assertEquals(2, mDecodedProto.wifiConfigStoreIo.readDurations[0].count);
4635 
4636         assertEquals(50, mDecodedProto.wifiConfigStoreIo.readDurations[1].rangeStartMs);
4637         assertEquals(100, mDecodedProto.wifiConfigStoreIo.readDurations[1].rangeEndMs);
4638         assertEquals(1, mDecodedProto.wifiConfigStoreIo.readDurations[1].count);
4639 
4640         assertEquals(100, mDecodedProto.wifiConfigStoreIo.readDurations[2].rangeStartMs);
4641         assertEquals(150, mDecodedProto.wifiConfigStoreIo.readDurations[2].rangeEndMs);
4642         assertEquals(2, mDecodedProto.wifiConfigStoreIo.readDurations[2].count);
4643 
4644         assertEquals(200, mDecodedProto.wifiConfigStoreIo.readDurations[3].rangeStartMs);
4645         assertEquals(300, mDecodedProto.wifiConfigStoreIo.readDurations[3].rangeEndMs);
4646         assertEquals(1, mDecodedProto.wifiConfigStoreIo.readDurations[3].count);
4647 
4648         assertEquals(300, mDecodedProto.wifiConfigStoreIo.readDurations[4].rangeStartMs);
4649         assertEquals(Integer.MAX_VALUE,
4650                 mDecodedProto.wifiConfigStoreIo.readDurations[4].rangeEndMs);
4651         assertEquals(1, mDecodedProto.wifiConfigStoreIo.readDurations[4].count);
4652     }
4653 
4654     /**
4655      * Test the generation of 'WifiConfigStoreIODuration' write histograms.
4656      */
4657     @Test
testWifiConfigStoreWriteDurationsHistogramGeneration()4658     public void testWifiConfigStoreWriteDurationsHistogramGeneration() throws Exception {
4659         mWifiMetrics.noteWifiConfigStoreWriteDuration(10);
4660         mWifiMetrics.noteWifiConfigStoreWriteDuration(40);
4661         mWifiMetrics.noteWifiConfigStoreWriteDuration(60);
4662         mWifiMetrics.noteWifiConfigStoreWriteDuration(90);
4663         mWifiMetrics.noteWifiConfigStoreWriteDuration(534);
4664         mWifiMetrics.noteWifiConfigStoreWriteDuration(345);
4665 
4666         dumpProtoAndDeserialize();
4667 
4668         assertEquals(0, mDecodedProto.wifiConfigStoreIo.readDurations.length);
4669         assertEquals(3, mDecodedProto.wifiConfigStoreIo.writeDurations.length);
4670 
4671         assertEquals(Integer.MIN_VALUE,
4672                 mDecodedProto.wifiConfigStoreIo.writeDurations[0].rangeStartMs);
4673         assertEquals(50, mDecodedProto.wifiConfigStoreIo.writeDurations[0].rangeEndMs);
4674         assertEquals(2, mDecodedProto.wifiConfigStoreIo.writeDurations[0].count);
4675 
4676         assertEquals(50, mDecodedProto.wifiConfigStoreIo.writeDurations[1].rangeStartMs);
4677         assertEquals(100, mDecodedProto.wifiConfigStoreIo.writeDurations[1].rangeEndMs);
4678         assertEquals(2, mDecodedProto.wifiConfigStoreIo.writeDurations[1].count);
4679 
4680         assertEquals(300, mDecodedProto.wifiConfigStoreIo.writeDurations[2].rangeStartMs);
4681         assertEquals(Integer.MAX_VALUE,
4682                 mDecodedProto.wifiConfigStoreIo.writeDurations[2].rangeEndMs);
4683         assertEquals(2, mDecodedProto.wifiConfigStoreIo.writeDurations[2].count);
4684     }
4685 
4686     /**
4687      * Test link probe metrics.
4688      */
4689     @Test
testLogLinkProbeMetrics()4690     public void testLogLinkProbeMetrics() throws Exception {
4691         mWifiMetrics.logLinkProbeSuccess(TEST_IFACE_NAME, 10000, -75, 50, 5);
4692         mWifiMetrics.logLinkProbeFailure(TEST_IFACE_NAME, 30000, -80, 10,
4693                 WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_NO_ACK);
4694         mWifiMetrics.logLinkProbeSuccess(TEST_IFACE_NAME, 3000, -71, 160, 12);
4695         mWifiMetrics.logLinkProbeFailure(TEST_IFACE_NAME, 40000, -80, 6,
4696                 WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_NO_ACK);
4697         mWifiMetrics.logLinkProbeSuccess(TEST_IFACE_NAME, 5000, -73, 160, 10);
4698         mWifiMetrics.logLinkProbeFailure(TEST_IFACE_NAME, 2000, -78, 6,
4699                 WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_TIMEOUT);
4700 
4701         dumpProtoAndDeserialize();
4702 
4703         StaEvent[] expected = {
4704                 buildLinkProbeSuccessStaEvent(5),
4705                 buildLinkProbeFailureStaEvent(LinkProbeStats.LINK_PROBE_FAILURE_REASON_NO_ACK),
4706                 buildLinkProbeSuccessStaEvent(12),
4707                 buildLinkProbeFailureStaEvent(LinkProbeStats.LINK_PROBE_FAILURE_REASON_NO_ACK),
4708                 buildLinkProbeSuccessStaEvent(10),
4709                 buildLinkProbeFailureStaEvent(LinkProbeStats.LINK_PROBE_FAILURE_REASON_TIMEOUT)
4710         };
4711         assertLinkProbeStaEventsEqual(expected, mDecodedProto.staEventList);
4712 
4713         LinkProbeStats linkProbeStats = mDecodedProto.linkProbeStats;
4714 
4715         Int32Count[] expectedSuccessRssiHistogram = {
4716                 buildInt32Count(-75, 1),
4717                 buildInt32Count(-73, 1),
4718                 buildInt32Count(-71, 1),
4719         };
4720         assertKeyCountsEqual(expectedSuccessRssiHistogram,
4721                 linkProbeStats.successRssiCounts);
4722 
4723         Int32Count[] expectedFailureRssiHistogram = {
4724                 buildInt32Count(-80, 2),
4725                 buildInt32Count(-78, 1),
4726         };
4727         assertKeyCountsEqual(expectedFailureRssiHistogram,
4728                 linkProbeStats.failureRssiCounts);
4729 
4730         Int32Count[] expectedSuccessLinkSpeedHistogram = {
4731                 buildInt32Count(50, 1),
4732                 buildInt32Count(160, 2)
4733         };
4734         assertKeyCountsEqual(expectedSuccessLinkSpeedHistogram,
4735                 linkProbeStats.successLinkSpeedCounts);
4736 
4737         Int32Count[] expectedFailureLinkSpeedHistogram = {
4738                 buildInt32Count(6, 2),
4739                 buildInt32Count(10, 1)
4740         };
4741         assertKeyCountsEqual(expectedFailureLinkSpeedHistogram,
4742                 linkProbeStats.failureLinkSpeedCounts);
4743 
4744         HistogramBucketInt32[] expectedSuccessTimeSinceLastTxSuccessSecondsHistogram = {
4745                 buildHistogramBucketInt32(Integer.MIN_VALUE, 5, 1),
4746                 buildHistogramBucketInt32(5, 15, 2)
4747         };
4748         assertHistogramBucketsEqual(expectedSuccessTimeSinceLastTxSuccessSecondsHistogram,
4749                 linkProbeStats.successSecondsSinceLastTxSuccessHistogram);
4750 
4751         HistogramBucketInt32[] expectedFailureTimeSinceLastTxSuccessSecondsHistogram = {
4752                 buildHistogramBucketInt32(Integer.MIN_VALUE, 5, 1),
4753                 buildHistogramBucketInt32(15, 45, 2)
4754         };
4755         assertHistogramBucketsEqual(expectedFailureTimeSinceLastTxSuccessSecondsHistogram,
4756                 linkProbeStats.failureSecondsSinceLastTxSuccessHistogram);
4757 
4758         HistogramBucketInt32[] expectedSuccessElapsedTimeMsHistogram = {
4759                 buildHistogramBucketInt32(5, 10, 1),
4760                 buildHistogramBucketInt32(10, 15, 2),
4761         };
4762         assertHistogramBucketsEqual(expectedSuccessElapsedTimeMsHistogram,
4763                 linkProbeStats.successElapsedTimeMsHistogram);
4764 
4765         LinkProbeFailureReasonCount[] expectedFailureReasonCount = {
4766                 buildLinkProbeFailureReasonCount(
4767                         LinkProbeStats.LINK_PROBE_FAILURE_REASON_NO_ACK, 2),
4768                 buildLinkProbeFailureReasonCount(
4769                         LinkProbeStats.LINK_PROBE_FAILURE_REASON_TIMEOUT, 1),
4770         };
4771         assertLinkProbeFailureReasonCountsEqual(expectedFailureReasonCount,
4772                 linkProbeStats.failureReasonCounts);
4773     }
4774 
4775     /**
4776      * Tests counting the number of link probes triggered per day for each experiment.
4777      */
4778     @Test
testIncrementLinkProbeExperimentProbeCount()4779     public void testIncrementLinkProbeExperimentProbeCount() throws Exception {
4780         String experimentId1 = "screenOnDelay=6000,noTxDelay=3000,delayBetweenProbes=9000,"
4781                 + "rssiThreshold=-70,linkSpeedThreshold=15,";
4782         mWifiMetrics.incrementLinkProbeExperimentProbeCount(experimentId1);
4783 
4784         String experimentId2 = "screenOnDelay=9000,noTxDelay=12000,delayBetweenProbes=15000,"
4785                 + "rssiThreshold=-72,linkSpeedThreshold=20,";
4786         mWifiMetrics.incrementLinkProbeExperimentProbeCount(experimentId2);
4787         mWifiMetrics.incrementLinkProbeExperimentProbeCount(experimentId2);
4788 
4789         dumpProtoAndDeserialize();
4790 
4791         ExperimentProbeCounts[] actual = mDecodedProto.linkProbeStats.experimentProbeCounts;
4792 
4793         ExperimentProbeCounts[] expected = {
4794                 buildExperimentProbeCounts(experimentId1, 1),
4795                 buildExperimentProbeCounts(experimentId2, 2)
4796         };
4797 
4798         assertExperimentProbeCountsEqual(expected, actual);
4799     }
4800 
4801     /**
4802      * Tests logNetworkSelectionDecision()
4803      */
4804     @Test
testLogNetworkSelectionDecision()4805     public void testLogNetworkSelectionDecision() throws Exception {
4806         mWifiMetrics.logNetworkSelectionDecision(1, 2, true, 6);
4807         mWifiMetrics.logNetworkSelectionDecision(1, 2, false, 1);
4808         mWifiMetrics.logNetworkSelectionDecision(1, 2, true, 6);
4809         mWifiMetrics.logNetworkSelectionDecision(1, 2, true, 2);
4810         mWifiMetrics.logNetworkSelectionDecision(3, 2, false, 15);
4811         mWifiMetrics.logNetworkSelectionDecision(1, 2, false, 6);
4812         mWifiMetrics.logNetworkSelectionDecision(1, 4, true, 2);
4813 
4814         dumpProtoAndDeserialize();
4815 
4816         assertEquals(3, mDecodedProto.networkSelectionExperimentDecisionsList.length);
4817 
4818         NetworkSelectionExperimentDecisions exp12 =
4819                 findUniqueNetworkSelectionExperimentDecisions(1, 2);
4820         Int32Count[] exp12SameExpected = {
4821                 buildInt32Count(2, 1),
4822                 buildInt32Count(6, 2)
4823         };
4824         assertKeyCountsEqual(exp12SameExpected, exp12.sameSelectionNumChoicesCounter);
4825         Int32Count[] exp12DiffExpected = {
4826                 buildInt32Count(1, 1),
4827                 buildInt32Count(6, 1)
4828         };
4829         assertKeyCountsEqual(exp12DiffExpected, exp12.differentSelectionNumChoicesCounter);
4830 
4831         NetworkSelectionExperimentDecisions exp32 =
4832                 findUniqueNetworkSelectionExperimentDecisions(3, 2);
4833         Int32Count[] exp32SameExpected = {};
4834         assertKeyCountsEqual(exp32SameExpected, exp32.sameSelectionNumChoicesCounter);
4835         Int32Count[] exp32DiffExpected = {
4836                 buildInt32Count(
4837                         WifiMetrics.NetworkSelectionExperimentResults.MAX_CHOICES, 1)
4838         };
4839         assertKeyCountsEqual(exp32DiffExpected, exp32.differentSelectionNumChoicesCounter);
4840 
4841         NetworkSelectionExperimentDecisions exp14 =
4842                 findUniqueNetworkSelectionExperimentDecisions(1, 4);
4843         Int32Count[] exp14SameExpected = {
4844                 buildInt32Count(2, 1)
4845         };
4846         assertKeyCountsEqual(exp14SameExpected, exp14.sameSelectionNumChoicesCounter);
4847         Int32Count[] exp14DiffExpected = {};
4848         assertKeyCountsEqual(exp14DiffExpected, exp14.differentSelectionNumChoicesCounter);
4849     }
4850 
4851     /**
4852      * Test the generation of 'WifiNetworkRequestApiLog' message.
4853      */
4854     @Test
testWifiNetworkRequestApiLog()4855     public void testWifiNetworkRequestApiLog() throws Exception {
4856         mWifiMetrics.incrementNetworkRequestApiNumRequest();
4857         mWifiMetrics.incrementNetworkRequestApiNumRequest();
4858         mWifiMetrics.incrementNetworkRequestApiNumRequest();
4859 
4860         mWifiMetrics.incrementNetworkRequestApiMatchSizeHistogram(7);
4861         mWifiMetrics.incrementNetworkRequestApiMatchSizeHistogram(0);
4862         mWifiMetrics.incrementNetworkRequestApiMatchSizeHistogram(1);
4863 
4864         mWifiMetrics.incrementNetworkRequestApiNumConnectSuccessOnPrimaryIface();
4865         mWifiMetrics.incrementNetworkRequestApiNumConnectSuccessOnPrimaryIface();
4866 
4867         mWifiMetrics.incrementNetworkRequestApiNumConnectSuccessOnSecondaryIface();
4868 
4869         mWifiMetrics.incrementNetworkRequestApiNumConnectOnPrimaryIface();
4870         mWifiMetrics.incrementNetworkRequestApiNumConnectOnPrimaryIface();
4871 
4872         mWifiMetrics.incrementNetworkRequestApiNumConnectOnSecondaryIface();
4873         mWifiMetrics.incrementNetworkRequestApiNumConnectOnSecondaryIface();
4874         mWifiMetrics.incrementNetworkRequestApiNumConnectOnSecondaryIface();
4875 
4876         mWifiMetrics.incrementNetworkRequestApiNumUserApprovalBypass();
4877         mWifiMetrics.incrementNetworkRequestApiNumUserApprovalBypass();
4878 
4879         mWifiMetrics.incrementNetworkRequestApiNumUserReject();
4880 
4881         mWifiMetrics.incrementNetworkRequestApiNumApps();
4882 
4883         mWifiMetrics.incrementNetworkRequestApiConnectionDurationSecOnPrimaryIfaceHistogram(40);
4884         mWifiMetrics.incrementNetworkRequestApiConnectionDurationSecOnPrimaryIfaceHistogram(670);
4885         mWifiMetrics.incrementNetworkRequestApiConnectionDurationSecOnPrimaryIfaceHistogram(1801);
4886 
4887         mWifiMetrics.incrementNetworkRequestApiConnectionDurationSecOnSecondaryIfaceHistogram(100);
4888         mWifiMetrics.incrementNetworkRequestApiConnectionDurationSecOnSecondaryIfaceHistogram(350);
4889         mWifiMetrics.incrementNetworkRequestApiConnectionDurationSecOnSecondaryIfaceHistogram(750);
4890 
4891         mWifiMetrics.incrementNetworkRequestApiConcurrentConnectionDurationSecHistogram(10);
4892         mWifiMetrics.incrementNetworkRequestApiConcurrentConnectionDurationSecHistogram(589);
4893         mWifiMetrics.incrementNetworkRequestApiConcurrentConnectionDurationSecHistogram(2900);
4894         mWifiMetrics.incrementNetworkRequestApiConcurrentConnectionDurationSecHistogram(145);
4895 
4896         dumpProtoAndDeserialize();
4897 
4898         assertEquals(3, mDecodedProto.wifiNetworkRequestApiLog.numRequest);
4899         assertEquals(2, mDecodedProto.wifiNetworkRequestApiLog.numConnectSuccessOnPrimaryIface);
4900         assertEquals(1, mDecodedProto.wifiNetworkRequestApiLog.numConnectSuccessOnSecondaryIface);
4901         assertEquals(2, mDecodedProto.wifiNetworkRequestApiLog.numConnectOnPrimaryIface);
4902         assertEquals(3, mDecodedProto.wifiNetworkRequestApiLog.numConnectOnSecondaryIface);
4903         assertEquals(2, mDecodedProto.wifiNetworkRequestApiLog.numUserApprovalBypass);
4904         assertEquals(1, mDecodedProto.wifiNetworkRequestApiLog.numUserReject);
4905         assertEquals(1, mDecodedProto.wifiNetworkRequestApiLog.numApps);
4906 
4907         HistogramBucketInt32[] expectedNetworkMatchSizeHistogram = {
4908                 buildHistogramBucketInt32(0, 1, 1),
4909                 buildHistogramBucketInt32(1, 5, 1),
4910                 buildHistogramBucketInt32(5, 10, 1)
4911         };
4912         assertHistogramBucketsEqual(expectedNetworkMatchSizeHistogram,
4913                 mDecodedProto.wifiNetworkRequestApiLog.networkMatchSizeHistogram);
4914 
4915         HistogramBucketInt32[] expectedConnectionDurationOnPrimarySec = {
4916                 buildHistogramBucketInt32(0, toIntExact(Duration.ofMinutes(3).getSeconds()), 1),
4917                 buildHistogramBucketInt32(toIntExact(Duration.ofMinutes(10).getSeconds()),
4918                         toIntExact(Duration.ofMinutes(30).getSeconds()), 1),
4919                 buildHistogramBucketInt32(toIntExact(Duration.ofMinutes(30).getSeconds()),
4920                         toIntExact(Duration.ofHours(1).getSeconds()), 1)
4921         };
4922         assertHistogramBucketsEqual(expectedConnectionDurationOnPrimarySec,
4923                 mDecodedProto.wifiNetworkRequestApiLog
4924                         .connectionDurationSecOnPrimaryIfaceHistogram);
4925 
4926         HistogramBucketInt32[] expectedConnectionDurationOnSecondarySec = {
4927                 buildHistogramBucketInt32(0, toIntExact(Duration.ofMinutes(3).getSeconds()), 1),
4928                 buildHistogramBucketInt32(toIntExact(Duration.ofMinutes(3).getSeconds()),
4929                         toIntExact(Duration.ofMinutes(10).getSeconds()), 1),
4930                 buildHistogramBucketInt32(toIntExact(Duration.ofMinutes(10).getSeconds()),
4931                         toIntExact(Duration.ofMinutes(30).getSeconds()), 1),
4932         };
4933         assertHistogramBucketsEqual(expectedConnectionDurationOnSecondarySec,
4934                 mDecodedProto.wifiNetworkRequestApiLog
4935                         .connectionDurationSecOnSecondaryIfaceHistogram);
4936 
4937         HistogramBucketInt32[] expectedConcurrentConnectionDuration = {
4938                 buildHistogramBucketInt32(0, toIntExact(Duration.ofMinutes(3).getSeconds()), 2),
4939                 buildHistogramBucketInt32(toIntExact(Duration.ofMinutes(3).getSeconds()),
4940                         toIntExact(Duration.ofMinutes(10).getSeconds()), 1),
4941                 buildHistogramBucketInt32(toIntExact(Duration.ofMinutes(30).getSeconds()),
4942                         toIntExact(Duration.ofHours(1).getSeconds()), 1)
4943         };
4944         assertHistogramBucketsEqual(expectedConcurrentConnectionDuration,
4945                 mDecodedProto.wifiNetworkRequestApiLog.concurrentConnectionDurationSecHistogram);
4946     }
4947 
4948     /**
4949      * Test the generation of 'WifiNetworkSuggestionApiLog' message.
4950      */
4951     @Test
testWifiNetworkSuggestionApiLog()4952     public void testWifiNetworkSuggestionApiLog() throws Exception {
4953         mWifiMetrics.incrementNetworkSuggestionApiNumModification();
4954         mWifiMetrics.incrementNetworkSuggestionApiNumModification();
4955         mWifiMetrics.incrementNetworkSuggestionApiNumModification();
4956         mWifiMetrics.incrementNetworkSuggestionApiNumModification();
4957 
4958         mWifiMetrics.incrementNetworkSuggestionApiNumConnectSuccess();
4959         mWifiMetrics.incrementNetworkSuggestionApiNumConnectSuccess();
4960 
4961         mWifiMetrics.incrementNetworkSuggestionApiNumConnectFailure();
4962 
4963         mWifiMetrics.incrementNetworkSuggestionApiUsageNumOfAppInType(
4964                 WifiNetworkSuggestionsManager.APP_TYPE_NON_PRIVILEGED);
4965         mWifiMetrics.incrementNetworkSuggestionApiUsageNumOfAppInType(
4966                 WifiNetworkSuggestionsManager.APP_TYPE_NON_PRIVILEGED);
4967         mWifiMetrics.incrementNetworkSuggestionApiUsageNumOfAppInType(
4968                 WifiNetworkSuggestionsManager.APP_TYPE_NON_PRIVILEGED);
4969         mWifiMetrics.incrementNetworkSuggestionApiUsageNumOfAppInType(
4970                 WifiNetworkSuggestionsManager.APP_TYPE_CARRIER_PRIVILEGED);
4971         mWifiMetrics.incrementNetworkSuggestionApiUsageNumOfAppInType(
4972                 WifiNetworkSuggestionsManager.APP_TYPE_CARRIER_PRIVILEGED);
4973         mWifiMetrics.incrementNetworkSuggestionApiUsageNumOfAppInType(
4974                 WifiNetworkSuggestionsManager.APP_TYPE_NETWORK_PROVISIONING);
4975 
4976 
4977         mWifiMetrics.noteNetworkSuggestionApiListSizeHistogram(new ArrayList<Integer>() {{
4978                 add(5);
4979                 add(100);
4980                 add(50);
4981                 add(120);
4982             }});
4983         // Second update should overwrite the prevous write.
4984         mWifiMetrics.noteNetworkSuggestionApiListSizeHistogram(new ArrayList<Integer>() {{
4985                 add(7);
4986                 add(110);
4987                 add(40);
4988                 add(60);
4989             }});
4990 
4991         mWifiMetrics.incrementNetworkSuggestionUserRevokePermission();
4992         mWifiMetrics.incrementNetworkSuggestionUserRevokePermission();
4993 
4994         mWifiMetrics.addSuggestionExistsForSavedNetwork("savedNetwork");
4995         mWifiMetrics.incrementNetworkSuggestionMoreThanOneSuggestionForSingleScanResult();
4996         mWifiMetrics.addNetworkSuggestionPriorityGroup(0);
4997         mWifiMetrics.addNetworkSuggestionPriorityGroup(1);
4998         mWifiMetrics.addNetworkSuggestionPriorityGroup(1);
4999 
5000         dumpProtoAndDeserialize();
5001 
5002         assertEquals(4, mDecodedProto.wifiNetworkSuggestionApiLog.numModification);
5003         assertEquals(2, mDecodedProto.wifiNetworkSuggestionApiLog.numConnectSuccess);
5004         assertEquals(1, mDecodedProto.wifiNetworkSuggestionApiLog.numConnectFailure);
5005 
5006         HistogramBucketInt32[] expectedNetworkListSizeHistogram = {
5007                 buildHistogramBucketInt32(5, 20, 1),
5008                 buildHistogramBucketInt32(20, 50, 1),
5009                 buildHistogramBucketInt32(50, 100, 1),
5010                 buildHistogramBucketInt32(100, 500, 1),
5011         };
5012         assertHistogramBucketsEqual(expectedNetworkListSizeHistogram,
5013                 mDecodedProto.wifiNetworkSuggestionApiLog.networkListSizeHistogram);
5014 
5015         assertEquals(3, mDecodedProto.wifiNetworkSuggestionApiLog.appCountPerType.length);
5016         assertEquals(WifiMetricsProto.WifiNetworkSuggestionApiLog.TYPE_CARRIER_PRIVILEGED,
5017                 mDecodedProto.wifiNetworkSuggestionApiLog.appCountPerType[0].appType);
5018         assertEquals(2, mDecodedProto.wifiNetworkSuggestionApiLog.appCountPerType[0].count);
5019         assertEquals(WifiMetricsProto.WifiNetworkSuggestionApiLog.TYPE_NETWORK_PROVISIONING,
5020                 mDecodedProto.wifiNetworkSuggestionApiLog.appCountPerType[1].appType);
5021         assertEquals(1, mDecodedProto.wifiNetworkSuggestionApiLog.appCountPerType[1].count);
5022         assertEquals(WifiMetricsProto.WifiNetworkSuggestionApiLog.TYPE_NON_PRIVILEGED,
5023                 mDecodedProto.wifiNetworkSuggestionApiLog.appCountPerType[2].appType);
5024         assertEquals(3, mDecodedProto.wifiNetworkSuggestionApiLog.appCountPerType[2].count);
5025         assertEquals(1, mDecodedProto.wifiNetworkSuggestionApiLog.numMultipleSuggestions);
5026         assertEquals(1, mDecodedProto.wifiNetworkSuggestionApiLog
5027                 .numSavedNetworksWithConfiguredSuggestion);
5028         assertEquals(1, mDecodedProto.wifiNetworkSuggestionApiLog.numPriorityGroups);
5029     }
5030 
5031     /**
5032      * Test the generation of 'UserReactionToApprovalUiEvent' message.
5033      */
5034     @Test
testUserReactionToApprovalUiEvent()5035     public void testUserReactionToApprovalUiEvent() throws Exception {
5036         mWifiMetrics.addUserApprovalSuggestionAppUiReaction(1,  true);
5037         mWifiMetrics.addUserApprovalSuggestionAppUiReaction(2,  false);
5038 
5039         mWifiMetrics.addUserApprovalCarrierUiReaction(
5040                 WifiCarrierInfoManager.ACTION_USER_ALLOWED_CARRIER, true);
5041         mWifiMetrics.addUserApprovalCarrierUiReaction(
5042                 WifiCarrierInfoManager.ACTION_USER_DISMISS, false);
5043         mWifiMetrics.addUserApprovalCarrierUiReaction(
5044                 WifiCarrierInfoManager.ACTION_USER_DISALLOWED_CARRIER, false);
5045 
5046         dumpProtoAndDeserialize();
5047 
5048         assertEquals(2,
5049                 mDecodedProto.userReactionToApprovalUiEvent.userApprovalAppUiReaction.length);
5050         assertEquals(WifiMetricsProto.UserReactionToApprovalUiEvent.ACTION_ALLOWED,
5051                 mDecodedProto.userReactionToApprovalUiEvent.userApprovalAppUiReaction[0]
5052                         .userAction);
5053         assertEquals(true,
5054                 mDecodedProto.userReactionToApprovalUiEvent.userApprovalAppUiReaction[0]
5055                         .isDialog);
5056         assertEquals(WifiMetricsProto.UserReactionToApprovalUiEvent.ACTION_DISALLOWED,
5057                 mDecodedProto.userReactionToApprovalUiEvent.userApprovalAppUiReaction[1]
5058                         .userAction);
5059         assertEquals(false,
5060                 mDecodedProto.userReactionToApprovalUiEvent.userApprovalAppUiReaction[1]
5061                         .isDialog);
5062 
5063         assertEquals(3,
5064                 mDecodedProto.userReactionToApprovalUiEvent.userApprovalCarrierUiReaction.length);
5065         assertEquals(WifiMetricsProto.UserReactionToApprovalUiEvent.ACTION_ALLOWED,
5066                 mDecodedProto.userReactionToApprovalUiEvent.userApprovalCarrierUiReaction[0]
5067                         .userAction);
5068         assertEquals(true,
5069                 mDecodedProto.userReactionToApprovalUiEvent.userApprovalCarrierUiReaction[0]
5070                         .isDialog);
5071         assertEquals(WifiMetricsProto.UserReactionToApprovalUiEvent.ACTION_DISMISS,
5072                 mDecodedProto.userReactionToApprovalUiEvent.userApprovalCarrierUiReaction[1]
5073                         .userAction);
5074         assertEquals(false,
5075                 mDecodedProto.userReactionToApprovalUiEvent.userApprovalCarrierUiReaction[1]
5076                         .isDialog);
5077         assertEquals(WifiMetricsProto.UserReactionToApprovalUiEvent.ACTION_DISALLOWED,
5078                 mDecodedProto.userReactionToApprovalUiEvent.userApprovalCarrierUiReaction[2]
5079                         .userAction);
5080         assertEquals(false,
5081                 mDecodedProto.userReactionToApprovalUiEvent.userApprovalCarrierUiReaction[2]
5082                         .isDialog);
5083     }
5084 
findUniqueNetworkSelectionExperimentDecisions( int experiment1Id, int experiment2Id)5085     private NetworkSelectionExperimentDecisions findUniqueNetworkSelectionExperimentDecisions(
5086             int experiment1Id, int experiment2Id) {
5087         NetworkSelectionExperimentDecisions result = null;
5088         for (NetworkSelectionExperimentDecisions d
5089                 : mDecodedProto.networkSelectionExperimentDecisionsList) {
5090             if (d.experiment1Id == experiment1Id && d.experiment2Id == experiment2Id) {
5091                 assertNull("duplicate found!", result);
5092                 result = d;
5093             }
5094         }
5095         assertNotNull("not found!", result);
5096         return result;
5097     }
5098 
5099     /**
5100      * Verify that the label and the triggerType of Wifi usability stats are saved correctly
5101      * during IP reachability lost message is received.
5102      * @throws Exception
5103      */
5104     @Test
verifyIpReachabilityLostUpdatesWifiUsabilityMetrics()5105     public void verifyIpReachabilityLostUpdatesWifiUsabilityMetrics() throws Exception {
5106         WifiInfo info = mock(WifiInfo.class);
5107         when(info.getRssi()).thenReturn(nextRandInt());
5108         when(info.getLinkSpeed()).thenReturn(nextRandInt());
5109         long eventTimeMs = nextRandInt();
5110         when(mClock.getElapsedSinceBootMillis()).thenReturn(eventTimeMs);
5111         WifiLinkLayerStats stats1 = nextRandomStats(new WifiLinkLayerStats());
5112         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats1);
5113 
5114         // Add 1 LABEL_GOOD
5115         WifiLinkLayerStats statsGood = addGoodWifiUsabilityStats(nextRandomStats(stats1));
5116         // IP reachability lost occurs
5117         mWifiMetrics.addToWifiUsabilityStatsList(TEST_IFACE_NAME, WifiUsabilityStats.LABEL_BAD,
5118                 WifiUsabilityStats.TYPE_IP_REACHABILITY_LOST, -1);
5119 
5120         dumpProtoAndDeserialize();
5121         assertEquals(2, mDecodedProto.wifiUsabilityStatsList.length);
5122         WifiUsabilityStats[] statsList = mDecodedProto.wifiUsabilityStatsList;
5123         assertEquals(WifiUsabilityStats.LABEL_BAD, statsList[1].label);
5124         assertEquals(WifiUsabilityStats.TYPE_IP_REACHABILITY_LOST, statsList[1].triggerType);
5125         assertEquals(eventTimeMs, statsList[1].timeStampMs);
5126     }
5127 
5128     /**
5129      * Test the WifiLock active session statistics
5130      */
5131     @Test
testWifiLockActiveSession()5132     public void testWifiLockActiveSession() throws Exception {
5133         mWifiMetrics.addWifiLockActiveSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF, 100000);
5134         mWifiMetrics.addWifiLockActiveSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF, 10000);
5135         mWifiMetrics.addWifiLockActiveSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF, 10000000);
5136         mWifiMetrics.addWifiLockActiveSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF, 1000);
5137 
5138         mWifiMetrics.addWifiLockActiveSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, 90000);
5139         mWifiMetrics.addWifiLockActiveSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, 900000);
5140         mWifiMetrics.addWifiLockActiveSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, 9000);
5141         mWifiMetrics.addWifiLockActiveSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, 20000000);
5142 
5143         dumpProtoAndDeserialize();
5144 
5145         assertEquals(10111000, mDecodedProto.wifiLockStats.highPerfActiveTimeMs);
5146         assertEquals(20999000, mDecodedProto.wifiLockStats.lowLatencyActiveTimeMs);
5147 
5148         HistogramBucketInt32[] expectedHighPerfHistogram = {
5149                 buildHistogramBucketInt32(1, 10, 1),
5150                 buildHistogramBucketInt32(10, 60, 1),
5151                 buildHistogramBucketInt32(60, 600, 1),
5152                 buildHistogramBucketInt32(3600, Integer.MAX_VALUE, 1),
5153         };
5154 
5155         HistogramBucketInt32[] expectedLowLatencyHistogram = {
5156                 buildHistogramBucketInt32(1, 10, 1),
5157                 buildHistogramBucketInt32(60, 600, 1),
5158                 buildHistogramBucketInt32(600, 3600, 1),
5159                 buildHistogramBucketInt32(3600, Integer.MAX_VALUE, 1),
5160         };
5161 
5162         assertHistogramBucketsEqual(expectedHighPerfHistogram,
5163                 mDecodedProto.wifiLockStats.highPerfActiveSessionDurationSecHistogram);
5164 
5165         assertHistogramBucketsEqual(expectedLowLatencyHistogram,
5166                 mDecodedProto.wifiLockStats.lowLatencyActiveSessionDurationSecHistogram);
5167     }
5168 
5169     /**
5170      * Test the WifiLock acquisition session statistics
5171      */
5172     @Test
testWifiLockAcqSession()5173     public void testWifiLockAcqSession() throws Exception {
5174         mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF, 100000);
5175         mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF, 10000);
5176         mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF, 10000000);
5177         mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF, 1000);
5178 
5179         mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, 90000);
5180         mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, 900000);
5181         mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, 9000);
5182         mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, 20000000);
5183 
5184         dumpProtoAndDeserialize();
5185 
5186         HistogramBucketInt32[] expectedHighPerfHistogram = {
5187                 buildHistogramBucketInt32(1, 10, 1),
5188                 buildHistogramBucketInt32(10, 60, 1),
5189                 buildHistogramBucketInt32(60, 600, 1),
5190                 buildHistogramBucketInt32(3600, Integer.MAX_VALUE, 1),
5191         };
5192 
5193         HistogramBucketInt32[] expectedLowLatencyHistogram = {
5194                 buildHistogramBucketInt32(1, 10, 1),
5195                 buildHistogramBucketInt32(60, 600, 1),
5196                 buildHistogramBucketInt32(600, 3600, 1),
5197                 buildHistogramBucketInt32(3600, Integer.MAX_VALUE, 1),
5198         };
5199 
5200         assertHistogramBucketsEqual(expectedHighPerfHistogram,
5201                 mDecodedProto.wifiLockStats.highPerfLockAcqDurationSecHistogram);
5202 
5203         assertHistogramBucketsEqual(expectedLowLatencyHistogram,
5204                 mDecodedProto.wifiLockStats.lowLatencyLockAcqDurationSecHistogram);
5205     }
5206 
5207     /**
5208      * Verify that LABEL_GOOD stats are generated if Wifi score breaches low and there
5209      * is no WifiIsUnusableEvent in MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS millis
5210      * @throws Exception
5211      */
5212     @Test
testGoodStatsAreGeneratedByWifiScoreBreachLow()5213     public void testGoodStatsAreGeneratedByWifiScoreBreachLow() throws Exception {
5214         // The elapsed time falls into the interval for adding good stats
5215         createTestForDataCollectionByScoreBreach(
5216                 WifiMetrics.MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS + 1,
5217                 false, true);
5218         dumpProtoAndDeserialize();
5219         assertEquals(2, mDecodedProto.wifiUsabilityStatsList.length);
5220     }
5221 
5222     /**
5223      * Verify that LABEL_GOOD stats are not generated if Wifi score breaches low and the checking
5224      * time is less than MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS millis
5225      * @throws Exception
5226      */
5227     @Test
testGoodStatsAreNotGeneratedByWifiScoreBreachLow()5228     public void testGoodStatsAreNotGeneratedByWifiScoreBreachLow() throws Exception {
5229         // The elapsed time is shorter than necessary to add good stats
5230         createTestForDataCollectionByScoreBreach(
5231                 WifiMetrics.MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS - 1,
5232                 false, true);
5233         dumpProtoAndDeserialize();
5234         assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length);
5235     }
5236 
5237     /**
5238      * Verify that LABEL_GOOD stats are not generated if Wifi score breaches low and the checking
5239      * time is greater than VALIDITY_PERIOD_OF_SCORE_BREACH_LOW_MS
5240      * @throws Exception
5241      */
5242     @Test
testGoodStatsAreNotGeneratedIfWifiScoreBreachExpires()5243     public void testGoodStatsAreNotGeneratedIfWifiScoreBreachExpires() throws Exception {
5244         // The Wifi score breaching expires for adding good stats
5245         createTestForDataCollectionByScoreBreach(
5246                 WifiMetrics.VALIDITY_PERIOD_OF_SCORE_BREACH_LOW_MS + 1,
5247                 false, true);
5248         dumpProtoAndDeserialize();
5249         assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length);
5250     }
5251 
5252     /**
5253      * Verify that LABEL_GOOD stats are not generated if Wifi score breaches low and there is
5254      * WifiIsUnusableEvent occured within MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS millis
5255      * @throws Exception
5256      */
5257     @Test
testGoodStatsAreNotGeneratedIfBadEventOccured()5258     public void testGoodStatsAreNotGeneratedIfBadEventOccured() throws Exception {
5259         // The elapsed time falls into the interval for adding good stats and bad event occurs
5260         createTestForDataCollectionByScoreBreach(
5261                 WifiMetrics.MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS + 1,
5262                 true, true);
5263         dumpProtoAndDeserialize();
5264         assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length);
5265     }
5266 
5267     /**
5268      * Verify that LABEL_GOOD stats are generated if Wifi usability score breaches low and there
5269      * is no WifiIsUnusableEvent in MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS millis
5270      * @throws Exception
5271      */
5272     @Test
testGoodStatsAreGeneratedByWifiUsabilityScoreBreachLow()5273     public void testGoodStatsAreGeneratedByWifiUsabilityScoreBreachLow() throws Exception {
5274         // The elapsed time falls into the interval for adding good stats
5275         createTestForDataCollectionByScoreBreach(
5276                 WifiMetrics.MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS + 1,
5277                 false, false);
5278         dumpProtoAndDeserialize();
5279         assertEquals(2, mDecodedProto.wifiUsabilityStatsList.length);
5280     }
5281 
5282     /**
5283      * Verify that LABEL_GOOD stats are not generated if Wifi usability score breaches low and
5284      * the checking time is less than MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS millis
5285      * @throws Exception
5286      */
5287     @Test
testGoodStatsAreNotGeneratedByWifiUsabilityScoreBreachLow()5288     public void testGoodStatsAreNotGeneratedByWifiUsabilityScoreBreachLow() throws Exception {
5289         // The elapsed time is shorter than necessary to add good stats
5290         createTestForDataCollectionByScoreBreach(
5291                 WifiMetrics.MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS - 1,
5292                 false, false);
5293         dumpProtoAndDeserialize();
5294         assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length);
5295     }
5296 
5297     /**
5298      * Verify that LABEL_GOOD stats are not generated if Wifi usability score breaches low and
5299      * the checking time is greater than VALIDITY_PERIOD_OF_SCORE_BREACH_LOW_MS
5300      * @throws Exception
5301      */
5302     @Test
testGoodStatsAreNotGeneratedIfWifiUsabilityScoreBreachExpires()5303     public void testGoodStatsAreNotGeneratedIfWifiUsabilityScoreBreachExpires() throws Exception {
5304         // The Wifi usability score breaching expires for adding good stats
5305         createTestForDataCollectionByScoreBreach(
5306                 WifiMetrics.VALIDITY_PERIOD_OF_SCORE_BREACH_LOW_MS + 1,
5307                 false, false);
5308         dumpProtoAndDeserialize();
5309         assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length);
5310     }
5311 
5312     /**
5313      * Verify that LABEL_GOOD stats are not generated if Wifi usability score breaches low and there
5314      * is WifiIsUnusableEvent occured within MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS millis
5315      * @throws Exception
5316      */
5317     @Test
testGoodStatsAreNotGeneratedIfBadEventOccuredForUsabilityScore()5318     public void testGoodStatsAreNotGeneratedIfBadEventOccuredForUsabilityScore() throws Exception {
5319         // The elapsed time falls into the interval for adding good stats and bad event occurs
5320         createTestForDataCollectionByScoreBreach(
5321                 WifiMetrics.MIN_SCORE_BREACH_TO_GOOD_STATS_WAIT_TIME_MS + 1,
5322                 true, false);
5323         dumpProtoAndDeserialize();
5324         assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length);
5325     }
5326 
5327     /**
5328      * Verify that incrementNumWifiToggles increments the corrects fields based on input.
5329      */
5330     @Test
testIncrementNumWifiToggles()5331     public void testIncrementNumWifiToggles() throws Exception {
5332         mWifiMetrics.incrementNumWifiToggles(true, true);
5333         for (int i = 0; i < 2; i++) {
5334             mWifiMetrics.incrementNumWifiToggles(true, false);
5335         }
5336         for (int i = 0; i < 3; i++) {
5337             mWifiMetrics.incrementNumWifiToggles(false, true);
5338         }
5339         for (int i = 0; i < 4; i++) {
5340             mWifiMetrics.incrementNumWifiToggles(false, false);
5341         }
5342         dumpProtoAndDeserialize();
5343         assertEquals(1, mDecodedProto.wifiToggleStats.numToggleOnPrivileged);
5344         assertEquals(2, mDecodedProto.wifiToggleStats.numToggleOffPrivileged);
5345         assertEquals(3, mDecodedProto.wifiToggleStats.numToggleOnNormal);
5346         assertEquals(4, mDecodedProto.wifiToggleStats.numToggleOffNormal);
5347     }
5348 
5349     /**
5350      * Verify metered stats are counted properly for saved and ephemeral networks.
5351      */
5352     @Test
testMeteredNetworkMetrics()5353     public void testMeteredNetworkMetrics() throws Exception {
5354         // Test without metered override
5355         WifiConfiguration config = WifiConfigurationTestUtil.createPskNetwork();
5356         WifiConfiguration config1 = WifiConfigurationTestUtil.createPskNetwork();
5357         config.fromWifiNetworkSuggestion = false;
5358         config1.fromWifiNetworkSuggestion = true;
5359         mWifiMetrics.addMeteredStat(config, false);
5360         mWifiMetrics.addMeteredStat(config1, true);
5361         dumpProtoAndDeserialize();
5362         assertEquals(0, mDecodedProto.meteredNetworkStatsSaved.numMetered);
5363         assertEquals(1, mDecodedProto.meteredNetworkStatsSaved.numUnmetered);
5364         assertEquals(0, mDecodedProto.meteredNetworkStatsSaved.numOverrideMetered);
5365         assertEquals(0, mDecodedProto.meteredNetworkStatsSaved.numOverrideUnmetered);
5366         assertEquals(1, mDecodedProto.meteredNetworkStatsSuggestion.numMetered);
5367         assertEquals(0, mDecodedProto.meteredNetworkStatsSuggestion.numUnmetered);
5368         assertEquals(0, mDecodedProto.meteredNetworkStatsSuggestion.numOverrideMetered);
5369         assertEquals(0, mDecodedProto.meteredNetworkStatsSuggestion.numOverrideUnmetered);
5370 
5371         // Test with metered override
5372         config = WifiConfigurationTestUtil.createPskNetwork();
5373         config1 = WifiConfigurationTestUtil.createPskNetwork();
5374         config.meteredOverride = WifiConfiguration.METERED_OVERRIDE_METERED;
5375         config1.meteredOverride = WifiConfiguration.METERED_OVERRIDE_NOT_METERED;
5376         mWifiMetrics.addMeteredStat(config, true);
5377         mWifiMetrics.addMeteredStat(config1, true);
5378         dumpProtoAndDeserialize();
5379         assertEquals(1, mDecodedProto.meteredNetworkStatsSaved.numMetered);
5380         assertEquals(1, mDecodedProto.meteredNetworkStatsSaved.numUnmetered);
5381         assertEquals(1, mDecodedProto.meteredNetworkStatsSaved.numOverrideMetered);
5382         assertEquals(1, mDecodedProto.meteredNetworkStatsSaved.numOverrideUnmetered);
5383         assertEquals(0, mDecodedProto.meteredNetworkStatsSuggestion.numMetered);
5384         assertEquals(0, mDecodedProto.meteredNetworkStatsSuggestion.numUnmetered);
5385         assertEquals(0, mDecodedProto.meteredNetworkStatsSuggestion.numOverrideMetered);
5386         assertEquals(0, mDecodedProto.meteredNetworkStatsSuggestion.numOverrideUnmetered);
5387     }
5388 
5389     /**
5390      * Verify that the same network does not get counted twice
5391      */
5392     @Test
testMeteredNetworkMetricsNoDoubleCount()5393     public void testMeteredNetworkMetricsNoDoubleCount() throws Exception {
5394         WifiConfiguration config = new WifiConfiguration();
5395         config.ephemeral = false;
5396         mWifiMetrics.addMeteredStat(config, false);
5397         mWifiMetrics.addMeteredStat(config, true);
5398         mWifiMetrics.addMeteredStat(config, true);
5399         dumpProtoAndDeserialize();
5400         assertEquals(1, mDecodedProto.meteredNetworkStatsSaved.numMetered);
5401         assertEquals(0, mDecodedProto.meteredNetworkStatsSaved.numUnmetered);
5402         assertEquals(0, mDecodedProto.meteredNetworkStatsSaved.numOverrideMetered);
5403         assertEquals(0, mDecodedProto.meteredNetworkStatsSaved.numOverrideUnmetered);
5404         assertEquals(0, mDecodedProto.meteredNetworkStatsSuggestion.numMetered);
5405         assertEquals(0, mDecodedProto.meteredNetworkStatsSuggestion.numUnmetered);
5406         assertEquals(0, mDecodedProto.meteredNetworkStatsSuggestion.numOverrideMetered);
5407         assertEquals(0, mDecodedProto.meteredNetworkStatsSuggestion.numOverrideUnmetered);
5408     }
5409 
5410     /**
5411      * Create a test to verify data collection logic triggered by score breaching low
5412      * @param elapsedTimeAfterBreach The elapsed time after score breaches low
5413      * @param isThereBadEvent Whether there is a bad event happened after score breaches low
5414      * @param isWifiScore Whether it is Wifi score or not that breaches the threshold
5415      */
createTestForDataCollectionByScoreBreach( long elapsedTimeAfterBreach, boolean isThereBadEvent, boolean isWifiScore)5416     private void createTestForDataCollectionByScoreBreach(
5417             long elapsedTimeAfterBreach, boolean isThereBadEvent, boolean isWifiScore) {
5418         WifiInfo info = mock(WifiInfo.class);
5419         when(info.getRssi()).thenReturn(nextRandInt());
5420         when(info.getLinkSpeed()).thenReturn(nextRandInt());
5421         WifiLinkLayerStats stats2 = new WifiLinkLayerStats();
5422         mWifiMetrics.setWifiState(TEST_IFACE_NAME, WifiMetricsProto.WifiLog.WIFI_ASSOCIATED);
5423 
5424         addOneBadWifiUsabilityStats(info);
5425         if (isWifiScore) {
5426             stats2 = wifiScoreBreachesLow(info, stats2);
5427         } else {
5428             stats2 = wifiUsabilityScoreBreachesLow(info, stats2);
5429         }
5430         if (isThereBadEvent) {
5431             mWifiMetrics.logWifiIsUnusableEvent(TEST_IFACE_NAME,
5432                     WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX, -1);
5433         }
5434         when(mClock.getElapsedSinceBootMillis()).thenReturn(elapsedTimeAfterBreach);
5435         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats2);
5436     }
5437 
5438     // Simulate adding one LABEL_BAD WifiUsabilityStats
addOneBadWifiUsabilityStats(WifiInfo info)5439     private void addOneBadWifiUsabilityStats(WifiInfo info) {
5440         WifiLinkLayerStats stats1 = new WifiLinkLayerStats();
5441         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats1);
5442         mWifiMetrics.addToWifiUsabilityStatsList(TEST_IFACE_NAME, WifiUsabilityStats.LABEL_BAD,
5443                 WifiUsabilityStats.TYPE_DATA_STALL_BAD_TX, -1);
5444     }
5445 
5446     // Simulate that Wifi score breaches low
wifiScoreBreachesLow(WifiInfo info, WifiLinkLayerStats stats2)5447     private WifiLinkLayerStats wifiScoreBreachesLow(WifiInfo info, WifiLinkLayerStats stats2) {
5448         int upper = WifiMetrics.LOW_WIFI_SCORE + 7;
5449         int lower = WifiMetrics.LOW_WIFI_SCORE - 8;
5450         mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, upper);
5451         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats2);
5452         stats2 = nextRandomStats(stats2);
5453         long timeMs = 0;
5454         when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs);
5455         // Wifi score breaches low
5456         mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, lower);
5457         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats2);
5458         stats2 = nextRandomStats(stats2);
5459         return stats2;
5460     }
5461 
5462     // Simulate that Wifi usability score breaches low
wifiUsabilityScoreBreachesLow(WifiInfo info, WifiLinkLayerStats stats2)5463     private WifiLinkLayerStats wifiUsabilityScoreBreachesLow(WifiInfo info,
5464             WifiLinkLayerStats stats2) {
5465         int upper = WifiMetrics.LOW_WIFI_USABILITY_SCORE + 7;
5466         int lower = WifiMetrics.LOW_WIFI_USABILITY_SCORE - 8;
5467         mWifiMetrics.incrementWifiUsabilityScoreCount(TEST_IFACE_NAME, 1, upper, 30);
5468         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats2);
5469         stats2 = nextRandomStats(stats2);
5470         long timeMs = 0;
5471         when(mClock.getElapsedSinceBootMillis()).thenReturn(timeMs);
5472         // Wifi usability score breaches low
5473         mWifiMetrics.incrementWifiUsabilityScoreCount(TEST_IFACE_NAME, 2, lower, 30);
5474         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats2);
5475         stats2 = nextRandomStats(stats2);
5476         return stats2;
5477     }
5478 
5479     /**
5480      * Verify the counts of passpoint profile type are correct.
5481      * @param profileTypes type and count of installed passpoint profiles
5482      */
assertPasspointProfileTypeCount(PasspointProfileTypeCount[] profileTypes)5483     private void assertPasspointProfileTypeCount(PasspointProfileTypeCount[] profileTypes) {
5484         for (PasspointProfileTypeCount passpointProfileType : profileTypes) {
5485             switch(passpointProfileType.eapMethodType) {
5486                 case PasspointProfileTypeCount.TYPE_EAP_AKA:
5487                     assertEquals(NUM_EAP_AKA_TYPE, passpointProfileType.count);
5488                     break;
5489                 case PasspointProfileTypeCount.TYPE_EAP_AKA_PRIME:
5490                     assertEquals(NUM_EAP_AKA_PRIME_TYPE, passpointProfileType.count);
5491                     break;
5492                 case PasspointProfileTypeCount.TYPE_EAP_SIM:
5493                     assertEquals(NUM_EAP_SIM_TYPE, passpointProfileType.count);
5494                     break;
5495                 case PasspointProfileTypeCount.TYPE_EAP_TLS:
5496                     assertEquals(NUM_EAP_TLS_TYPE, passpointProfileType.count);
5497                     break;
5498                 case PasspointProfileTypeCount.TYPE_EAP_TTLS:
5499                     assertEquals(NUM_EAP_TTLS_TYPE, passpointProfileType.count);
5500                     break;
5501                 default:
5502                     fail("unknown type counted");
5503             }
5504         }
5505     }
5506 
5507     /**
5508      * Verify that the LABEL_BAD Wifi usability stats are not saved if screen state is off.
5509      * @throws Exception
5510      */
5511     @Test
verifyLabelBadStatsAreNotSavedIfScreenIsOff()5512     public void verifyLabelBadStatsAreNotSavedIfScreenIsOff() throws Exception {
5513         setScreenState(false);
5514         WifiInfo info = mock(WifiInfo.class);
5515         when(info.getRssi()).thenReturn(nextRandInt());
5516         when(info.getLinkSpeed()).thenReturn(nextRandInt());
5517         WifiLinkLayerStats stats1 = nextRandomStats(new WifiLinkLayerStats());
5518         mWifiMetrics.updateWifiUsabilityStatsEntries(TEST_IFACE_NAME, info, stats1);
5519 
5520         // Add 1 LABEL_GOOD
5521         WifiLinkLayerStats statsGood = addGoodWifiUsabilityStats(nextRandomStats(stats1));
5522         // IP reachability lost occurs
5523         mWifiMetrics.addToWifiUsabilityStatsList(TEST_IFACE_NAME, WifiUsabilityStats.LABEL_BAD,
5524                 WifiUsabilityStats.TYPE_IP_REACHABILITY_LOST, -1);
5525         // Wifi data stall occurs
5526         mWifiMetrics.addToWifiUsabilityStatsList(TEST_IFACE_NAME, WifiUsabilityStats.LABEL_BAD,
5527                 WifiIsUnusableEvent.TYPE_DATA_STALL_BAD_TX, -1);
5528         // Firmware alert occurs
5529         mWifiMetrics.logFirmwareAlert(TEST_IFACE_NAME, 2);
5530 
5531         dumpProtoAndDeserialize();
5532         assertEquals(0, mDecodedProto.wifiUsabilityStatsList.length);
5533     }
5534 
5535     /**
5536      * Test the logging of connection duration stats
5537      */
5538     @Test
testConnectionDurationStats()5539     public void testConnectionDurationStats() throws Exception {
5540         for (int i = 0; i < 2; i++) {
5541             mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, 52);
5542             mWifiMetrics.incrementConnectionDuration(5000, false, true);
5543             mWifiMetrics.incrementWifiScoreCount(TEST_IFACE_NAME, 40);
5544             mWifiMetrics.incrementConnectionDuration(5000, false, true);
5545             mWifiMetrics.incrementConnectionDuration(3000, true, true);
5546             mWifiMetrics.incrementConnectionDuration(1000, false, false);
5547             mWifiMetrics.incrementConnectionDuration(500, true, false);
5548         }
5549         dumpProtoAndDeserialize();
5550 
5551         assertEquals(6000,
5552                 mDecodedProto.connectionDurationStats.totalTimeSufficientThroughputMs);
5553         assertEquals(20000,
5554                 mDecodedProto.connectionDurationStats.totalTimeInsufficientThroughputMs);
5555         assertEquals(10000,
5556                 mDecodedProto.connectionDurationStats.totalTimeInsufficientThroughputDefaultWifiMs);
5557         assertEquals(3000,
5558                 mDecodedProto.connectionDurationStats.totalTimeCellularDataOffMs);
5559     }
5560 
5561     /**
5562      * Test the logging of isExternalWifiScorerOn
5563      */
5564     @Test
testIsExternalWifiScorerOn()5565     public void testIsExternalWifiScorerOn() throws Exception {
5566         mWifiMetrics.setIsExternalWifiScorerOn(true);
5567         dumpProtoAndDeserialize();
5568         assertEquals(true, mDecodedProto.isExternalWifiScorerOn);
5569     }
5570 
5571     /*
5572      * Test the logging of Wi-Fi off
5573      */
5574     @Test
testWifiOff()5575     public void testWifiOff() throws Exception {
5576         // if not deferred, timeout and duration should be ignored.
5577         mWifiMetrics.noteWifiOff(false, false, 0);
5578         mWifiMetrics.noteWifiOff(false, true, 999);
5579 
5580         // deferred, not timed out
5581         mWifiMetrics.noteWifiOff(true, false, 0);
5582         mWifiMetrics.noteWifiOff(true, false, 1000);
5583 
5584         // deferred and timed out
5585         mWifiMetrics.noteWifiOff(true, true, 2000);
5586         mWifiMetrics.noteWifiOff(true, true, 2000);
5587         mWifiMetrics.noteWifiOff(true, true, 4000);
5588 
5589         dumpProtoAndDeserialize();
5590 
5591         assertEquals(7,
5592                 mDecodedProto.wifiOffMetrics.numWifiOff);
5593         assertEquals(5,
5594                 mDecodedProto.wifiOffMetrics.numWifiOffDeferring);
5595         assertEquals(3,
5596                 mDecodedProto.wifiOffMetrics.numWifiOffDeferringTimeout);
5597 
5598         Int32Count[] expectedHistogram = {
5599                 buildInt32Count(0, 1),
5600                 buildInt32Count(1000, 1),
5601                 buildInt32Count(2000, 2),
5602                 buildInt32Count(4000, 1),
5603         };
5604         assertKeyCountsEqual(expectedHistogram,
5605                 mDecodedProto.wifiOffMetrics.wifiOffDeferringTimeHistogram);
5606     }
5607 
5608     /*
5609      * Test the logging of Wi-Fi off
5610      */
5611     @Test
testSoftApConfigLimitationMetrics()5612     public void testSoftApConfigLimitationMetrics() throws Exception {
5613         SoftApConfiguration originalConfig = new SoftApConfiguration.Builder()
5614                 .setSsid("TestSSID").build();
5615         SoftApConfiguration needToResetCongig = new SoftApConfiguration.Builder(originalConfig)
5616                 .setPassphrase("TestPassphreas", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
5617                 .setClientControlByUserEnabled(true)
5618                 .setMaxNumberOfClients(10)
5619                 .build();
5620         mWifiMetrics.noteSoftApConfigReset(originalConfig, needToResetCongig);
5621 
5622         mWifiMetrics.noteSoftApClientBlocked(5);
5623         mWifiMetrics.noteSoftApClientBlocked(5);
5624         mWifiMetrics.noteSoftApClientBlocked(5);
5625         mWifiMetrics.noteSoftApClientBlocked(8);
5626 
5627         dumpProtoAndDeserialize();
5628 
5629         assertEquals(1,
5630                 mDecodedProto.softApConfigLimitationMetrics.numSecurityTypeResetToDefault);
5631         assertEquals(1,
5632                 mDecodedProto.softApConfigLimitationMetrics.numMaxClientSettingResetToDefault);
5633         assertEquals(1,
5634                 mDecodedProto.softApConfigLimitationMetrics.numClientControlByUserResetToDefault);
5635 
5636         Int32Count[] expectedHistogram = {
5637                 buildInt32Count(5, 3),
5638                 buildInt32Count(8, 1),
5639         };
5640         assertKeyCountsEqual(expectedHistogram,
5641                 mDecodedProto.softApConfigLimitationMetrics.maxClientSettingWhenReachHistogram);
5642     }
5643 
5644     /**
5645      * Test the logging of channel utilization
5646      */
5647     @Test
testChannelUtilization()5648     public void testChannelUtilization() throws Exception {
5649         mWifiMetrics.incrementChannelUtilizationCount(180, 2412);
5650         mWifiMetrics.incrementChannelUtilizationCount(150, 2412);
5651         mWifiMetrics.incrementChannelUtilizationCount(230, 2412);
5652         mWifiMetrics.incrementChannelUtilizationCount(20, 5510);
5653         mWifiMetrics.incrementChannelUtilizationCount(50, 5510);
5654 
5655         dumpProtoAndDeserialize();
5656 
5657         HistogramBucketInt32[] expected2GHistogram = {
5658                 buildHistogramBucketInt32(150, 175, 1),
5659                 buildHistogramBucketInt32(175, 200, 1),
5660                 buildHistogramBucketInt32(225, Integer.MAX_VALUE, 1),
5661         };
5662 
5663         HistogramBucketInt32[] expectedAbove2GHistogram = {
5664                 buildHistogramBucketInt32(Integer.MIN_VALUE, 25, 1),
5665                 buildHistogramBucketInt32(50, 75, 1),
5666         };
5667 
5668         assertHistogramBucketsEqual(expected2GHistogram,
5669                 mDecodedProto.channelUtilizationHistogram.utilization2G);
5670         assertHistogramBucketsEqual(expectedAbove2GHistogram,
5671                 mDecodedProto.channelUtilizationHistogram.utilizationAbove2G);
5672     }
5673 
5674     /**
5675      * Test the logging of Tx and Rx throughput
5676      */
5677     @Test
testThroughput()5678     public void testThroughput() throws Exception {
5679         mWifiMetrics.incrementThroughputKbpsCount(500, 800, 2412);
5680         mWifiMetrics.incrementThroughputKbpsCount(5_000, 4_000, 2412);
5681         mWifiMetrics.incrementThroughputKbpsCount(54_000, 48_000, 2412);
5682         mWifiMetrics.incrementThroughputKbpsCount(50_000, 49_000, 5510);
5683         mWifiMetrics.incrementThroughputKbpsCount(801_000, 790_000, 5510);
5684         mWifiMetrics.incrementThroughputKbpsCount(1100_000, 1200_000, 5510);
5685         mWifiMetrics.incrementThroughputKbpsCount(1599_000, 1800_000, 6120);
5686         dumpProtoAndDeserialize();
5687 
5688         HistogramBucketInt32[] expectedTx2GHistogramMbps = {
5689                 buildHistogramBucketInt32(Integer.MIN_VALUE, 1, 1),
5690                 buildHistogramBucketInt32(5, 10, 1),
5691                 buildHistogramBucketInt32(50, 100, 1),
5692         };
5693 
5694         HistogramBucketInt32[] expectedRx2GHistogramMbps = {
5695                 buildHistogramBucketInt32(Integer.MIN_VALUE, 1, 1),
5696                 buildHistogramBucketInt32(1, 5, 1),
5697                 buildHistogramBucketInt32(25, 50, 1),
5698         };
5699 
5700         HistogramBucketInt32[] expectedTxAbove2GHistogramMbps = {
5701                 buildHistogramBucketInt32(50, 100, 1),
5702                 buildHistogramBucketInt32(800, 1200, 2),
5703                 buildHistogramBucketInt32(1200, 1600, 1),
5704         };
5705 
5706         HistogramBucketInt32[] expectedRxAbove2GHistogramMbps = {
5707                 buildHistogramBucketInt32(25, 50, 1),
5708                 buildHistogramBucketInt32(600, 800, 1),
5709                 buildHistogramBucketInt32(1200, 1600, 1),
5710                 buildHistogramBucketInt32(1600, Integer.MAX_VALUE, 1),
5711         };
5712 
5713         assertHistogramBucketsEqual(expectedTx2GHistogramMbps,
5714                 mDecodedProto.throughputMbpsHistogram.tx2G);
5715         assertHistogramBucketsEqual(expectedTxAbove2GHistogramMbps,
5716                 mDecodedProto.throughputMbpsHistogram.txAbove2G);
5717         assertHistogramBucketsEqual(expectedRx2GHistogramMbps,
5718                 mDecodedProto.throughputMbpsHistogram.rx2G);
5719         assertHistogramBucketsEqual(expectedRxAbove2GHistogramMbps,
5720                 mDecodedProto.throughputMbpsHistogram.rxAbove2G);
5721     }
5722 
5723     /**
5724      * Test the Initial partial scan statistics
5725      */
5726     @Test
testInitPartialScan()5727     public void testInitPartialScan() throws Exception {
5728         mWifiMetrics.incrementInitialPartialScanCount();
5729         mWifiMetrics.reportInitialPartialScan(4, true);
5730         mWifiMetrics.incrementInitialPartialScanCount();
5731         mWifiMetrics.reportInitialPartialScan(2, false);
5732         mWifiMetrics.incrementInitialPartialScanCount();
5733         mWifiMetrics.incrementInitialPartialScanCount();
5734         mWifiMetrics.reportInitialPartialScan(1, false);
5735         mWifiMetrics.incrementInitialPartialScanCount();
5736         mWifiMetrics.reportInitialPartialScan(7, true);
5737         mWifiMetrics.incrementInitialPartialScanCount();
5738         mWifiMetrics.incrementInitialPartialScanCount();
5739         mWifiMetrics.reportInitialPartialScan(15, false);
5740         mWifiMetrics.incrementInitialPartialScanCount();
5741         mWifiMetrics.reportInitialPartialScan(2, true);
5742         mWifiMetrics.incrementInitialPartialScanCount();
5743         mWifiMetrics.reportInitialPartialScan(10, true);
5744 
5745         dumpProtoAndDeserialize();
5746 
5747         assertEquals(9, mDecodedProto.initPartialScanStats.numScans);
5748         assertEquals(4, mDecodedProto.initPartialScanStats.numSuccessScans);
5749         assertEquals(3, mDecodedProto.initPartialScanStats.numFailureScans);
5750 
5751         HistogramBucketInt32[] expectedSuccessScanHistogram = {
5752                 buildHistogramBucketInt32(1, 3, 1),
5753                 buildHistogramBucketInt32(3, 5, 1),
5754                 buildHistogramBucketInt32(5, 10, 1),
5755                 buildHistogramBucketInt32(10, Integer.MAX_VALUE, 1),
5756         };
5757 
5758         HistogramBucketInt32[] expectedFailureScanHistogram = {
5759                 buildHistogramBucketInt32(1, 3, 2),
5760                 buildHistogramBucketInt32(10, Integer.MAX_VALUE, 1),
5761         };
5762 
5763         assertHistogramBucketsEqual(expectedSuccessScanHistogram,
5764                 mDecodedProto.initPartialScanStats.successfulScanChannelCountHistogram);
5765 
5766         assertHistogramBucketsEqual(expectedFailureScanHistogram,
5767                 mDecodedProto.initPartialScanStats.failedScanChannelCountHistogram);
5768     }
5769 
5770     /**
5771      * Test overlapping and non-overlapping connection events return overlapping duration correctly
5772      */
5773     @Test
testOverlappingConnectionEvent()5774     public void testOverlappingConnectionEvent() throws Exception {
5775         // Connection event 1
5776         when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 0);
5777         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, mTestWifiConfig,
5778                 "TestNetwork", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
5779         when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 1000);
5780         // Connection event 2 overlaps with 1
5781         assertEquals(1000, mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, mTestWifiConfig,
5782                 "TestNetwork", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE));
5783 
5784         // Connection event 2 ends
5785         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
5786                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
5787                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
5788                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
5789         when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 2000);
5790         // Connection event 3 doesn't overlap with 2
5791         assertEquals(0, mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, mTestWifiConfig,
5792                 "TestNetwork", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE));
5793     }
5794 
5795     @Test
testCarrierWifiConnectionEvent()5796     public void testCarrierWifiConnectionEvent() throws Exception {
5797         mWifiMetrics.incrementNumOfCarrierWifiConnectionSuccess();
5798         for (int i = 0; i < 2; i++) {
5799             mWifiMetrics.incrementNumOfCarrierWifiConnectionAuthFailure();
5800         }
5801         for (int i = 0; i < 3; i++) {
5802             mWifiMetrics.incrementNumOfCarrierWifiConnectionNonAuthFailure();
5803         }
5804 
5805         dumpProtoAndDeserialize();
5806 
5807         assertEquals(1, mDecodedProto.carrierWifiMetrics.numConnectionSuccess);
5808         assertEquals(2, mDecodedProto.carrierWifiMetrics.numConnectionAuthFailure);
5809         assertEquals(3, mDecodedProto.carrierWifiMetrics.numConnectionNonAuthFailure);
5810     }
5811 
5812     /**
5813      * Verify the ConnectionEvent is labeled with networkType Passpoint correctly and that the OSU
5814      * provisioned flag is set to true.
5815      */
5816     @Test
testConnectionNetworkTypePasspointFromOsu()5817     public void testConnectionNetworkTypePasspointFromOsu() throws Exception {
5818         WifiConfiguration config = WifiConfigurationTestUtil.createPasspointNetwork();
5819         config.updateIdentifier = "7";
5820         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
5821                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_NONE);
5822         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
5823                 WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_TIMED_OUT,
5824                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
5825                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, 0);
5826         dumpProtoAndDeserialize();
5827 
5828         assertEquals(1, mDecodedProto.connectionEvent.length);
5829         assertEquals(WifiMetricsProto.ConnectionEvent.TYPE_PASSPOINT,
5830                 mDecodedProto.connectionEvent[0].networkType);
5831         assertTrue(mDecodedProto.connectionEvent[0].isOsuProvisioned);
5832     }
5833 
5834     @Test
testFirstConnectAfterBootStats()5835     public void testFirstConnectAfterBootStats() throws Exception {
5836         when(mClock.getElapsedSinceBootMillis()).thenReturn(1000L);
5837         mWifiMetrics.noteWifiEnabledDuringBoot(true);
5838 
5839         when(mClock.getElapsedSinceBootMillis()).thenReturn(2000L);
5840         mWifiMetrics.noteFirstNetworkSelectionAfterBoot(true);
5841 
5842         when(mClock.getElapsedSinceBootMillis()).thenReturn(3000L);
5843         mWifiMetrics.noteFirstL2ConnectionAfterBoot(true);
5844 
5845         when(mClock.getElapsedSinceBootMillis()).thenReturn(4000L);
5846         mWifiMetrics.noteFirstL3ConnectionAfterBoot(true);
5847 
5848         dumpProtoAndDeserialize();
5849 
5850         assertEquals(1000, mDecodedProto
5851                 .firstConnectAfterBootStats.wifiEnabledAtBoot.timestampSinceBootMillis);
5852         assertTrue(mDecodedProto.firstConnectAfterBootStats.wifiEnabledAtBoot.isSuccess);
5853         assertEquals(2000, mDecodedProto
5854                 .firstConnectAfterBootStats.firstNetworkSelection.timestampSinceBootMillis);
5855         assertTrue(mDecodedProto.firstConnectAfterBootStats.firstNetworkSelection.isSuccess);
5856         assertEquals(3000, mDecodedProto
5857                 .firstConnectAfterBootStats.firstL2Connection.timestampSinceBootMillis);
5858         assertTrue(mDecodedProto.firstConnectAfterBootStats.firstL2Connection.isSuccess);
5859         assertEquals(4000, mDecodedProto
5860                 .firstConnectAfterBootStats.firstL3Connection.timestampSinceBootMillis);
5861         assertTrue(mDecodedProto.firstConnectAfterBootStats.firstL3Connection.isSuccess);
5862     }
5863 
5864     @Test
testFirstConnectAfterBootStats_firstCallWins()5865     public void testFirstConnectAfterBootStats_firstCallWins() throws Exception {
5866         when(mClock.getElapsedSinceBootMillis()).thenReturn(1000L);
5867         mWifiMetrics.noteWifiEnabledDuringBoot(true);
5868 
5869         when(mClock.getElapsedSinceBootMillis()).thenReturn(2000L);
5870         mWifiMetrics.noteWifiEnabledDuringBoot(false);
5871 
5872         dumpProtoAndDeserialize();
5873 
5874         assertEquals(1000, mDecodedProto
5875                 .firstConnectAfterBootStats.wifiEnabledAtBoot.timestampSinceBootMillis);
5876         assertTrue(mDecodedProto.firstConnectAfterBootStats.wifiEnabledAtBoot.isSuccess);
5877     }
5878 
5879     @Test
testFirstConnectAfterBootStats_secondDumpNull()5880     public void testFirstConnectAfterBootStats_secondDumpNull() throws Exception {
5881         when(mClock.getElapsedSinceBootMillis()).thenReturn(1000L);
5882         mWifiMetrics.noteWifiEnabledDuringBoot(true);
5883 
5884         dumpProtoAndDeserialize();
5885 
5886         when(mClock.getElapsedSinceBootMillis()).thenReturn(2000L);
5887         mWifiMetrics.noteWifiEnabledDuringBoot(false);
5888 
5889         dumpProtoAndDeserialize();
5890 
5891         assertNull(mDecodedProto.firstConnectAfterBootStats);
5892     }
5893 
5894     @Test
testFirstConnectAfterBootStats_falseInvalidatesSubsequentCalls()5895     public void testFirstConnectAfterBootStats_falseInvalidatesSubsequentCalls() throws Exception {
5896         when(mClock.getElapsedSinceBootMillis()).thenReturn(1000L);
5897         mWifiMetrics.noteWifiEnabledDuringBoot(false);
5898 
5899         when(mClock.getElapsedSinceBootMillis()).thenReturn(2000L);
5900         mWifiMetrics.noteFirstNetworkSelectionAfterBoot(true);
5901 
5902         when(mClock.getElapsedSinceBootMillis()).thenReturn(3000L);
5903         mWifiMetrics.noteFirstL2ConnectionAfterBoot(true);
5904 
5905         when(mClock.getElapsedSinceBootMillis()).thenReturn(4000L);
5906         mWifiMetrics.noteFirstL3ConnectionAfterBoot(true);
5907 
5908         dumpProtoAndDeserialize();
5909 
5910         assertEquals(1000, mDecodedProto
5911                 .firstConnectAfterBootStats.wifiEnabledAtBoot.timestampSinceBootMillis);
5912         assertFalse(mDecodedProto.firstConnectAfterBootStats.wifiEnabledAtBoot.isSuccess);
5913         assertNull(mDecodedProto.firstConnectAfterBootStats.firstNetworkSelection);
5914         assertNull(mDecodedProto.firstConnectAfterBootStats.firstL2Connection);
5915         assertNull(mDecodedProto.firstConnectAfterBootStats.firstL3Connection);
5916     }
5917 
5918     @Test
testWifiConnectionResultAtomNotEmittedWithNoConnectionEndEvent()5919     public void testWifiConnectionResultAtomNotEmittedWithNoConnectionEndEvent() {
5920         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
5921                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
5922 
5923         ExtendedMockito.verify(() -> WifiStatsLog.write(
5924                 anyInt(), anyBoolean(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(),
5925                 anyBoolean(), anyInt()),
5926                 times(0));
5927     }
5928 
5929     @Test
testWifiConnectionResultAtomNotEmittedWithNoConnectionStartEvent()5930     public void testWifiConnectionResultAtomNotEmittedWithNoConnectionStartEvent() {
5931         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
5932                 WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
5933                 WifiMetricsProto.ConnectionEvent.HLF_DHCP,
5934                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, TEST_CANDIDATE_FREQ);
5935 
5936         ExtendedMockito.verify(() -> WifiStatsLog.write(
5937                 anyInt(), anyBoolean(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(),
5938                 anyBoolean(), anyInt()),
5939                 times(0));
5940     }
5941 
5942     @Test
testWifiConnectionResultAtomEmittedOnlyOnceWithMultipleConnectionEndEvents()5943     public void testWifiConnectionResultAtomEmittedOnlyOnceWithMultipleConnectionEndEvents() {
5944         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
5945                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
5946 
5947         for (int i = 0; i < 5; i++) {
5948             mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
5949                     WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
5950                     WifiMetricsProto.ConnectionEvent.HLF_DHCP,
5951                     WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, TEST_CANDIDATE_FREQ);
5952         }
5953 
5954         ExtendedMockito.verify(() -> WifiStatsLog.write(
5955                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED, false,
5956                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__FAILURE_CODE__FAILURE_AUTHENTICATION_GENERAL,
5957                 -80, 0,
5958                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__BAND__BAND_2G,
5959                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__AUTH_TYPE__AUTH_TYPE_WPA2_PSK,
5960                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__AUTOCONNECT_BOOT,
5961                 true,
5962                 0),
5963                 times(1));
5964     }
5965 
5966     @Test
testWifiConnectionResultAtomNewSessionOverwritesPreviousSession()5967     public void testWifiConnectionResultAtomNewSessionOverwritesPreviousSession() {
5968 
5969         WifiConfiguration config1 = createComplexWifiConfig();
5970         config1.getNetworkSelectionStatus().getCandidate().level = -50;
5971 
5972         WifiConfiguration config2 = createComplexWifiConfig();
5973         config2.getNetworkSelectionStatus().getCandidate().level = -60;
5974 
5975         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config1,
5976                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
5977 
5978         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config2,
5979                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
5980 
5981         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
5982                 WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
5983                 WifiMetricsProto.ConnectionEvent.HLF_DHCP,
5984                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, TEST_CANDIDATE_FREQ);
5985 
5986         ExtendedMockito.verify(() -> WifiStatsLog.write(
5987                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED, false,
5988                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__FAILURE_CODE__FAILURE_AUTHENTICATION_GENERAL,
5989                 -60, 0,
5990                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__BAND__BAND_2G,
5991                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__AUTH_TYPE__AUTH_TYPE_WPA2_PSK,
5992                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__AUTOCONNECT_BOOT,
5993                 true,
5994                 0),
5995                 times(1));
5996     }
5997 
5998     @Test
testWifiConnectionResultAtomHasCorrectTriggers()5999     public void testWifiConnectionResultAtomHasCorrectTriggers() {
6000         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
6001                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
6002 
6003         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
6004                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
6005                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
6006                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_NONE, TEST_CANDIDATE_FREQ);
6007 
6008         mWifiMetrics.reportNetworkDisconnect(TEST_IFACE_NAME, 0, 0, 0);
6009 
6010         ExtendedMockito.verify(() -> WifiStatsLog.write(
6011                 eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED), anyBoolean(),
6012                 anyInt(), anyInt(), anyInt(), anyInt(), anyInt(),
6013                 eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__AUTOCONNECT_BOOT),
6014                 anyBoolean(), anyInt()));
6015 
6016         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
6017                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
6018 
6019         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
6020                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
6021                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
6022                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_NONE, TEST_CANDIDATE_FREQ);
6023 
6024         mWifiMetrics.reportNetworkDisconnect(TEST_IFACE_NAME, 0, 0, 0);
6025 
6026         ExtendedMockito.verify(() -> WifiStatsLog.write(
6027                 eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED), anyBoolean(),
6028                 anyInt(), anyInt(), anyInt(), anyInt(), anyInt(),
6029                 eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__RECONNECT_SAME_NETWORK),
6030                 anyBoolean(), anyInt()));
6031 
6032         WifiConfiguration configOtherNetwork = createComplexWifiConfig();
6033         configOtherNetwork.networkId = 21;
6034         configOtherNetwork.SSID = "OtherNetwork";
6035         mWifiMetrics.setNominatorForNetwork(configOtherNetwork.networkId,
6036                 WifiMetricsProto.ConnectionEvent.NOMINATOR_SAVED);
6037 
6038         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, configOtherNetwork,
6039                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
6040 
6041         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
6042                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
6043                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
6044                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_NONE, TEST_CANDIDATE_FREQ);
6045 
6046         mWifiMetrics.reportNetworkDisconnect(TEST_IFACE_NAME, 0, 0, 0);
6047 
6048         ExtendedMockito.verify(() -> WifiStatsLog.write(
6049                 eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED), anyBoolean(),
6050                 anyInt(), anyInt(), anyInt(), anyInt(), anyInt(),
6051                 eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__AUTOCONNECT_CONFIGURED_NETWORK),
6052                 anyBoolean(), anyInt()));
6053 
6054         WifiConfiguration config = createComplexWifiConfig();
6055         config.networkId = 42;
6056         mWifiMetrics.setNominatorForNetwork(config.networkId,
6057                 WifiMetricsProto.ConnectionEvent.NOMINATOR_MANUAL);
6058 
6059         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, config,
6060                 "GREEN", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
6061 
6062         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
6063                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
6064                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
6065                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_NONE, TEST_CANDIDATE_FREQ);
6066 
6067         ExtendedMockito.verify(() -> WifiStatsLog.write(
6068                 eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED), anyBoolean(),
6069                 anyInt(), anyInt(), anyInt(), anyInt(), anyInt(),
6070                 eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__MANUAL),
6071                 anyBoolean(), anyInt()));
6072     }
6073 
6074     @Test
testWifiDisconnectAtomEmittedOnDisconnectFromSuccessfulSession()6075     public void testWifiDisconnectAtomEmittedOnDisconnectFromSuccessfulSession() {
6076         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
6077                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
6078 
6079         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
6080                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
6081                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
6082                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_NONE, TEST_CANDIDATE_FREQ);
6083 
6084         int linkSpeed = 100;
6085         int reason = 42;
6086         mWifiMetrics.reportNetworkDisconnect(TEST_IFACE_NAME, reason, TEST_CANDIDATE_LEVEL,
6087                 linkSpeed);
6088 
6089         ExtendedMockito.verify(() -> WifiStatsLog.write(
6090                 WifiStatsLog.WIFI_DISCONNECT_REPORTED,
6091                 0,
6092                 reason,
6093                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__BAND__BAND_2G,
6094                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__AUTH_TYPE__AUTH_TYPE_WPA2_PSK,
6095                 TEST_CANDIDATE_LEVEL,
6096                 linkSpeed));
6097     }
6098 
6099     @Test
testWifiDisconnectAtomNotEmittedOnDisconnectFromNotConnectedSession()6100     public void testWifiDisconnectAtomNotEmittedOnDisconnectFromNotConnectedSession() {
6101         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
6102                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
6103 
6104         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
6105                 WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
6106                 WifiMetricsProto.ConnectionEvent.HLF_DHCP,
6107                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, TEST_CANDIDATE_FREQ);
6108 
6109 
6110         int linkSpeed = 100;
6111         int reason = 42;
6112         mWifiMetrics.reportNetworkDisconnect(TEST_IFACE_NAME, reason, TEST_CANDIDATE_LEVEL,
6113                 linkSpeed);
6114 
6115         ExtendedMockito.verify(() -> WifiStatsLog.write(
6116                 eq(WifiStatsLog.WIFI_DISCONNECT_REPORTED),
6117                 anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()),
6118                 times(0));
6119     }
6120 
6121     @Test
testWifiDisconnectAtomNotEmittedWithNoSession()6122     public void testWifiDisconnectAtomNotEmittedWithNoSession() {
6123         mWifiMetrics.reportNetworkDisconnect(TEST_IFACE_NAME, 0, TEST_CANDIDATE_LEVEL, 0);
6124 
6125         ExtendedMockito.verify(() -> WifiStatsLog.write(
6126                 eq(WifiStatsLog.WIFI_DISCONNECT_REPORTED),
6127                 anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()),
6128                 times(0));
6129     }
6130 
6131     @Test
testWifiStateChangedAtomEmittedOnSuccessfulConnectAndDisconnect()6132     public void testWifiStateChangedAtomEmittedOnSuccessfulConnectAndDisconnect() {
6133         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
6134                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
6135 
6136         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
6137                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
6138                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
6139                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_NONE, TEST_CANDIDATE_FREQ);
6140 
6141         // TRUE must be emitted
6142         ExtendedMockito.verify(() -> WifiStatsLog.write(
6143                 WifiStatsLog.WIFI_CONNECTION_STATE_CHANGED,
6144                 true,
6145                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__BAND__BAND_2G,
6146                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__AUTH_TYPE__AUTH_TYPE_WPA2_PSK));
6147 
6148         int linkSpeed = 100;
6149         int reason = 42;
6150         mWifiMetrics.reportNetworkDisconnect(TEST_IFACE_NAME, reason, TEST_CANDIDATE_LEVEL,
6151                 linkSpeed);
6152 
6153         // FALSE must be emitted
6154         ExtendedMockito.verify(() -> WifiStatsLog.write(
6155                 WifiStatsLog.WIFI_CONNECTION_STATE_CHANGED,
6156                 false,
6157                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__BAND__BAND_2G,
6158                 WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__AUTH_TYPE__AUTH_TYPE_WPA2_PSK));
6159     }
6160 
6161     @Test
testWifiStateChangedAtomNotEmittedOnNotSuccessfulConnectAndDisconnect()6162     public void testWifiStateChangedAtomNotEmittedOnNotSuccessfulConnectAndDisconnect() {
6163         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
6164                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
6165 
6166         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
6167                 WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
6168                 WifiMetricsProto.ConnectionEvent.HLF_DHCP,
6169                 WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN, TEST_CANDIDATE_FREQ);
6170 
6171         // TRUE must not be emitted
6172         ExtendedMockito.verify(() -> WifiStatsLog.write(
6173                 eq(WifiStatsLog.WIFI_CONNECTION_STATE_CHANGED),
6174                 anyBoolean(), anyInt(), anyInt()),
6175                 times(0));
6176 
6177         int linkSpeed = 100;
6178         int reason = 42;
6179         mWifiMetrics.reportNetworkDisconnect(TEST_IFACE_NAME, reason, TEST_CANDIDATE_LEVEL,
6180                 linkSpeed);
6181 
6182         // But we still expect FALSE to be emitted
6183         ExtendedMockito.verify(() -> WifiStatsLog.write(
6184                 WifiStatsLog.WIFI_CONNECTION_STATE_CHANGED,
6185                 false,
6186                 0,
6187                 0));
6188     }
6189 
6190     @Test
testWifiConnectionResultTimeSinceLastConnectionCorrect()6191     public void testWifiConnectionResultTimeSinceLastConnectionCorrect() {
6192         when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 10 * 1000);
6193 
6194         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
6195                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
6196 
6197         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
6198                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
6199                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
6200                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_NONE, TEST_CANDIDATE_FREQ);
6201 
6202         ExtendedMockito.verify(() -> WifiStatsLog.write(
6203                 eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED), anyBoolean(),
6204                 anyInt(), anyInt(), anyInt(), anyInt(), anyInt(),
6205                 eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__AUTOCONNECT_BOOT),
6206                 anyBoolean(), eq(10)));
6207 
6208         mWifiMetrics.reportNetworkDisconnect(TEST_IFACE_NAME, 0, 0, 0);
6209 
6210         when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 30 * 1000);
6211 
6212         mWifiMetrics.startConnectionEvent(TEST_IFACE_NAME, createComplexWifiConfig(),
6213                 "RED", WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
6214 
6215         mWifiMetrics.endConnectionEvent(TEST_IFACE_NAME,
6216                 WifiMetrics.ConnectionEvent.FAILURE_NONE,
6217                 WifiMetricsProto.ConnectionEvent.HLF_NONE,
6218                 WifiMetricsProto.ConnectionEvent.AUTH_FAILURE_NONE, TEST_CANDIDATE_FREQ);
6219 
6220         ExtendedMockito.verify(() -> WifiStatsLog.write(
6221                 eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED), anyBoolean(),
6222                 anyInt(), anyInt(), anyInt(), anyInt(), anyInt(),
6223                 eq(WifiStatsLog.WIFI_CONNECTION_RESULT_REPORTED__TRIGGER__RECONNECT_SAME_NETWORK),
6224                 anyBoolean(), eq(20)));
6225 
6226         mWifiMetrics.reportNetworkDisconnect(TEST_IFACE_NAME, 0, 0, 0);
6227     }
6228 
6229     @Test
testWifiScanEmittedOnSuccess()6230     public void testWifiScanEmittedOnSuccess() {
6231         WifiMetrics.ScanMetrics scanMetrics = mWifiMetrics.getScanMetrics();
6232 
6233         scanMetrics.setImportance(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND);
6234         scanMetrics.logScanStarted(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE);
6235         scanMetrics.logScanSucceeded(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE, 4);
6236 
6237         ExtendedMockito.verify(() -> WifiStatsLog.write(
6238                 WifiStatsLog.WIFI_SCAN_REPORTED,
6239                 WifiStatsLog.WIFI_SCAN_REPORTED__TYPE__TYPE_SINGLE,
6240                 WifiStatsLog.WIFI_SCAN_REPORTED__RESULT__RESULT_SUCCESS,
6241                 WifiStatsLog.WIFI_SCAN_REPORTED__SOURCE__SOURCE_NO_WORK_SOURCE,
6242                 WifiStatsLog.WIFI_SCAN_REPORTED__IMPORTANCE__IMPORTANCE_FOREGROUND,
6243                 0, 4));
6244     }
6245 
6246     @Test
testWifiScanEmittedOnFailedToStart()6247     public void testWifiScanEmittedOnFailedToStart() {
6248         WifiMetrics.ScanMetrics scanMetrics = mWifiMetrics.getScanMetrics();
6249 
6250         scanMetrics.logScanFailedToStart(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE);
6251 
6252         ExtendedMockito.verify(() -> WifiStatsLog.write(
6253                 WifiStatsLog.WIFI_SCAN_REPORTED,
6254                 WifiStatsLog.WIFI_SCAN_REPORTED__TYPE__TYPE_SINGLE,
6255                 WifiStatsLog.WIFI_SCAN_REPORTED__RESULT__RESULT_FAILED_TO_START,
6256                 WifiStatsLog.WIFI_SCAN_REPORTED__SOURCE__SOURCE_NO_WORK_SOURCE,
6257                 WifiStatsLog.WIFI_SCAN_REPORTED__IMPORTANCE__IMPORTANCE_UNKNOWN,
6258                 0, 0));
6259     }
6260 
6261     @Test
testWifiScanEmittedOnFailure()6262     public void testWifiScanEmittedOnFailure() {
6263         WifiMetrics.ScanMetrics scanMetrics = mWifiMetrics.getScanMetrics();
6264 
6265         scanMetrics.logScanStarted(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE);
6266         scanMetrics.logScanFailed(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE);
6267 
6268         ExtendedMockito.verify(() -> WifiStatsLog.write(
6269                 WifiStatsLog.WIFI_SCAN_REPORTED,
6270                 WifiStatsLog.WIFI_SCAN_REPORTED__TYPE__TYPE_SINGLE,
6271                 WifiStatsLog.WIFI_SCAN_REPORTED__RESULT__RESULT_FAILED_TO_SCAN,
6272                 WifiStatsLog.WIFI_SCAN_REPORTED__SOURCE__SOURCE_NO_WORK_SOURCE,
6273                 WifiStatsLog.WIFI_SCAN_REPORTED__IMPORTANCE__IMPORTANCE_UNKNOWN,
6274                 0, 0));
6275     }
6276 
6277     @Test
testWifiScanNotEmittedWithNoStart()6278     public void testWifiScanNotEmittedWithNoStart() {
6279         WifiMetrics.ScanMetrics scanMetrics = mWifiMetrics.getScanMetrics();
6280 
6281         scanMetrics.logScanSucceeded(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE, 4);
6282 
6283         ExtendedMockito.verify(() -> WifiStatsLog.write(
6284                 eq(WifiStatsLog.WIFI_SCAN_REPORTED),
6285                 anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyInt()), times(0));
6286     }
6287 
6288     @Test
testWifiScanEmittedOnlyOnce()6289     public void testWifiScanEmittedOnlyOnce() {
6290         WifiMetrics.ScanMetrics scanMetrics = mWifiMetrics.getScanMetrics();
6291 
6292         scanMetrics.logScanStarted(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE);
6293         scanMetrics.logScanSucceeded(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE, 4);
6294         scanMetrics.logScanSucceeded(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE, 5);
6295         scanMetrics.logScanSucceeded(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE, 6);
6296 
6297         ExtendedMockito.verify(() -> WifiStatsLog.write(
6298                 eq(WifiStatsLog.WIFI_SCAN_REPORTED),
6299                 anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), eq(4)), times(1));
6300     }
6301 
6302     @Test
testWifiScanStatePreservedAfterStart()6303     public void testWifiScanStatePreservedAfterStart() {
6304         WifiMetrics.ScanMetrics scanMetrics = mWifiMetrics.getScanMetrics();
6305 
6306         scanMetrics.setImportance(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND);
6307         scanMetrics.logScanStarted(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE);
6308         scanMetrics.setImportance(ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE);
6309         scanMetrics.logScanSucceeded(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE, 4);
6310 
6311         ExtendedMockito.verify(() -> WifiStatsLog.write(
6312                 WifiStatsLog.WIFI_SCAN_REPORTED,
6313                 WifiStatsLog.WIFI_SCAN_REPORTED__TYPE__TYPE_SINGLE,
6314                 WifiStatsLog.WIFI_SCAN_REPORTED__RESULT__RESULT_SUCCESS,
6315                 WifiStatsLog.WIFI_SCAN_REPORTED__SOURCE__SOURCE_NO_WORK_SOURCE,
6316                 WifiStatsLog.WIFI_SCAN_REPORTED__IMPORTANCE__IMPORTANCE_FOREGROUND,
6317                 0, 4));
6318     }
6319 
6320     @Test
testWifiScanOverlappingRequestsOverwriteStateForSameType()6321     public void testWifiScanOverlappingRequestsOverwriteStateForSameType() {
6322         WifiMetrics.ScanMetrics scanMetrics = mWifiMetrics.getScanMetrics();
6323 
6324         scanMetrics.setImportance(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND);
6325         scanMetrics.logScanStarted(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE);
6326 
6327         scanMetrics.setImportance(ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE);
6328         scanMetrics.logScanStarted(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE);
6329 
6330         scanMetrics.logScanSucceeded(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE, 42);
6331         scanMetrics.logScanSucceeded(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE, 21);
6332 
6333         ExtendedMockito.verify(() -> WifiStatsLog.write(
6334                 WifiStatsLog.WIFI_SCAN_REPORTED,
6335                 WifiStatsLog.WIFI_SCAN_REPORTED__TYPE__TYPE_SINGLE,
6336                 WifiStatsLog.WIFI_SCAN_REPORTED__RESULT__RESULT_SUCCESS,
6337                 WifiStatsLog.WIFI_SCAN_REPORTED__SOURCE__SOURCE_NO_WORK_SOURCE,
6338                 WifiStatsLog.WIFI_SCAN_REPORTED__IMPORTANCE__IMPORTANCE_BACKGROUND,
6339                 0, 42));
6340     }
6341 
6342     @Test
testWifiScanOverlappingRequestsSeparateStatesForDifferentTypes()6343     public void testWifiScanOverlappingRequestsSeparateStatesForDifferentTypes() {
6344         WifiMetrics.ScanMetrics scanMetrics = mWifiMetrics.getScanMetrics();
6345 
6346         scanMetrics.setImportance(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND);
6347         scanMetrics.logScanStarted(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE);
6348 
6349         scanMetrics.setImportance(ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE);
6350         scanMetrics.logScanStarted(WifiMetrics.ScanMetrics.SCAN_TYPE_BACKGROUND);
6351 
6352         scanMetrics.logScanSucceeded(WifiMetrics.ScanMetrics.SCAN_TYPE_SINGLE, 42);
6353         scanMetrics.logScanSucceeded(WifiMetrics.ScanMetrics.SCAN_TYPE_BACKGROUND, 21);
6354 
6355         ExtendedMockito.verify(() -> WifiStatsLog.write(
6356                 WifiStatsLog.WIFI_SCAN_REPORTED,
6357                 WifiStatsLog.WIFI_SCAN_REPORTED__TYPE__TYPE_SINGLE,
6358                 WifiStatsLog.WIFI_SCAN_REPORTED__RESULT__RESULT_SUCCESS,
6359                 WifiStatsLog.WIFI_SCAN_REPORTED__SOURCE__SOURCE_NO_WORK_SOURCE,
6360                 WifiStatsLog.WIFI_SCAN_REPORTED__IMPORTANCE__IMPORTANCE_FOREGROUND,
6361                 0, 42));
6362 
6363         ExtendedMockito.verify(() -> WifiStatsLog.write(
6364                 WifiStatsLog.WIFI_SCAN_REPORTED,
6365                 WifiStatsLog.WIFI_SCAN_REPORTED__TYPE__TYPE_BACKGROUND,
6366                 WifiStatsLog.WIFI_SCAN_REPORTED__RESULT__RESULT_SUCCESS,
6367                 WifiStatsLog.WIFI_SCAN_REPORTED__SOURCE__SOURCE_NO_WORK_SOURCE,
6368                 WifiStatsLog.WIFI_SCAN_REPORTED__IMPORTANCE__IMPORTANCE_BACKGROUND,
6369                 0, 21));
6370     }
6371 
setScreenState(boolean screenOn)6372     private void setScreenState(boolean screenOn) {
6373         BroadcastReceiver broadcastReceiver = mBroadcastReceiverCaptor.getValue();
6374         assertNotNull(broadcastReceiver);
6375         Intent intent = new Intent(screenOn  ? ACTION_SCREEN_ON : ACTION_SCREEN_OFF);
6376         broadcastReceiver.onReceive(mContext, intent);
6377     }
6378 
6379     @Test
testWifiToWifiSwitchMetrics()6380     public void testWifiToWifiSwitchMetrics() throws Exception {
6381         // initially all 0
6382         dumpProtoAndDeserialize();
6383 
6384         assertFalse(mDecodedProto.wifiToWifiSwitchStats.isMakeBeforeBreakSupported);
6385         assertEquals(0, mDecodedProto.wifiToWifiSwitchStats.wifiToWifiSwitchTriggerCount);
6386         assertEquals(0, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakTriggerCount);
6387         assertEquals(0, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakNoInternetCount);
6388         assertEquals(0, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakRecoverPrimaryCount);
6389         assertEquals(0, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakInternetValidatedCount);
6390         assertEquals(0, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakSuccessCount);
6391         assertEquals(0, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakLingerCompletedCount);
6392         assertEquals(0,
6393                 mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakLingerDurationSeconds.length);
6394 
6395         // increment everything
6396         mWifiMetrics.setIsMakeBeforeBreakSupported(true);
6397         mWifiMetrics.incrementWifiToWifiSwitchTriggerCount();
6398         mWifiMetrics.incrementMakeBeforeBreakTriggerCount();
6399         mWifiMetrics.incrementMakeBeforeBreakNoInternetCount();
6400         mWifiMetrics.incrementMakeBeforeBreakRecoverPrimaryCount();
6401         mWifiMetrics.incrementMakeBeforeBreakInternetValidatedCount();
6402         mWifiMetrics.incrementMakeBeforeBreakSuccessCount();
6403         mWifiMetrics.incrementMakeBeforeBreakLingerCompletedCount(1000);
6404 
6405         dumpProtoAndDeserialize();
6406 
6407         // should be all 1
6408         assertTrue(mDecodedProto.wifiToWifiSwitchStats.isMakeBeforeBreakSupported);
6409         assertEquals(1, mDecodedProto.wifiToWifiSwitchStats.wifiToWifiSwitchTriggerCount);
6410         assertEquals(1, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakTriggerCount);
6411         assertEquals(1, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakNoInternetCount);
6412         assertEquals(1, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakRecoverPrimaryCount);
6413         assertEquals(1, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakInternetValidatedCount);
6414         assertEquals(1, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakSuccessCount);
6415         assertEquals(1, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakLingerCompletedCount);
6416         assertEquals(1,
6417                 mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakLingerDurationSeconds.length);
6418         assertEquals(1,
6419                 mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakLingerDurationSeconds[0].key);
6420         assertEquals(1,
6421                 mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakLingerDurationSeconds[0].count);
6422 
6423         // dump again
6424         dumpProtoAndDeserialize();
6425 
6426         // everything should be reset
6427         assertFalse(mDecodedProto.wifiToWifiSwitchStats.isMakeBeforeBreakSupported);
6428         assertEquals(0, mDecodedProto.wifiToWifiSwitchStats.wifiToWifiSwitchTriggerCount);
6429         assertEquals(0, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakTriggerCount);
6430         assertEquals(0, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakNoInternetCount);
6431         assertEquals(0, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakRecoverPrimaryCount);
6432         assertEquals(0, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakInternetValidatedCount);
6433         assertEquals(0, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakSuccessCount);
6434         assertEquals(0, mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakLingerCompletedCount);
6435         assertEquals(0,
6436                 mDecodedProto.wifiToWifiSwitchStats.makeBeforeBreakLingerDurationSeconds.length);
6437     }
6438 
6439     @Test
testPasspointConnectionMetrics()6440     public void testPasspointConnectionMetrics() throws Exception {
6441         // initially all 0
6442         dumpProtoAndDeserialize();
6443 
6444         assertEquals(0, mDecodedProto.totalNumberOfPasspointConnectionsWithVenueUrl);
6445         assertEquals(0, mDecodedProto.totalNumberOfPasspointConnectionsWithTermsAndConditionsUrl);
6446         assertEquals(0, mDecodedProto.totalNumberOfPasspointAcceptanceOfTermsAndConditions);
6447         assertEquals(0, mDecodedProto.totalNumberOfPasspointProfilesWithDecoratedIdentity);
6448         assertEquals(0, mDecodedProto.passpointDeauthImminentScope.length);
6449 
6450         // increment everything
6451         mWifiMetrics.incrementTotalNumberOfPasspointConnectionsWithVenueUrl();
6452         mWifiMetrics.incrementTotalNumberOfPasspointConnectionsWithTermsAndConditionsUrl();
6453         mWifiMetrics.incrementTotalNumberOfPasspointAcceptanceOfTermsAndConditions();
6454         mWifiMetrics.incrementTotalNumberOfPasspointProfilesWithDecoratedIdentity();
6455         mWifiMetrics.incrementPasspointDeauthImminentScope(true);
6456         mWifiMetrics.incrementPasspointDeauthImminentScope(false);
6457         mWifiMetrics.incrementPasspointDeauthImminentScope(false);
6458 
6459         dumpProtoAndDeserialize();
6460 
6461         Int32Count[] expectedDeauthImminentScope = {
6462                 buildInt32Count(WifiMetrics.PASSPOINT_DEAUTH_IMMINENT_SCOPE_ESS, 1),
6463                 buildInt32Count(WifiMetrics.PASSPOINT_DEAUTH_IMMINENT_SCOPE_BSS, 2),
6464         };
6465 
6466         assertEquals(1, mDecodedProto.totalNumberOfPasspointConnectionsWithVenueUrl);
6467         assertEquals(1, mDecodedProto.totalNumberOfPasspointConnectionsWithTermsAndConditionsUrl);
6468         assertEquals(1, mDecodedProto.totalNumberOfPasspointAcceptanceOfTermsAndConditions);
6469         assertEquals(1, mDecodedProto.totalNumberOfPasspointProfilesWithDecoratedIdentity);
6470         assertKeyCountsEqual(expectedDeauthImminentScope,
6471                 mDecodedProto.passpointDeauthImminentScope);
6472 
6473         // dump again
6474         dumpProtoAndDeserialize();
6475 
6476         // everything should be reset
6477         assertEquals(0, mDecodedProto.totalNumberOfPasspointConnectionsWithVenueUrl);
6478         assertEquals(0, mDecodedProto.totalNumberOfPasspointConnectionsWithTermsAndConditionsUrl);
6479         assertEquals(0, mDecodedProto.totalNumberOfPasspointAcceptanceOfTermsAndConditions);
6480         assertEquals(0, mDecodedProto.totalNumberOfPasspointProfilesWithDecoratedIdentity);
6481         assertEquals(0, mDecodedProto.passpointDeauthImminentScope.length);
6482     }
6483 
6484     @Test
testWifiStatsHealthStatWrite()6485     public void testWifiStatsHealthStatWrite() throws Exception {
6486         WifiInfo wifiInfo = mock(WifiInfo.class);
6487         when(wifiInfo.getFrequency()).thenReturn(5810);
6488         mWifiMetrics.incrementWifiScoreCount("",  60);
6489         mWifiMetrics.handlePollResult(TEST_IFACE_NAME, wifiInfo);
6490         mWifiMetrics.incrementConnectionDuration(3000, true, true);
6491         ExtendedMockito.verify(() -> WifiStatsLog.write(
6492                 WifiStatsLog.WIFI_HEALTH_STAT_REPORTED, 3000, true, true,
6493                 WifiStatsLog.WIFI_HEALTH_STAT_REPORTED__BAND__BAND_5G_HIGH));
6494 
6495         when(wifiInfo.getFrequency()).thenReturn(2412);
6496         mWifiMetrics.incrementWifiScoreCount("",  30);
6497         mWifiMetrics.handlePollResult(TEST_IFACE_NAME, wifiInfo);
6498         mWifiMetrics.incrementConnectionDuration(2000, false, true);
6499         ExtendedMockito.verify(() -> WifiStatsLog.write(
6500                 WifiStatsLog.WIFI_HEALTH_STAT_REPORTED, 2000, true, true,
6501                 WifiStatsLog.WIFI_HEALTH_STAT_REPORTED__BAND__BAND_2G));
6502     }
6503 
6504     /**
6505      * Test number of times connection failure status reported per
6506      * WifiConfiguration.RecentFailureReason
6507      */
6508     @Test
testRecentFailureAssociationStatusCount()6509     public void testRecentFailureAssociationStatusCount() throws Exception {
6510         mWifiMetrics.incrementRecentFailureAssociationStatusCount(
6511                 WifiConfiguration.RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA);
6512         mWifiMetrics.incrementRecentFailureAssociationStatusCount(
6513                 WifiConfiguration.RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA);
6514         mWifiMetrics.incrementRecentFailureAssociationStatusCount(
6515                 WifiConfiguration.RECENT_FAILURE_OCE_RSSI_BASED_ASSOCIATION_REJECTION);
6516         mWifiMetrics.incrementRecentFailureAssociationStatusCount(
6517                 WifiConfiguration.RECENT_FAILURE_MBO_ASSOC_DISALLOWED_AIR_INTERFACE_OVERLOADED);
6518         mWifiMetrics.incrementRecentFailureAssociationStatusCount(
6519                 WifiConfiguration.RECENT_FAILURE_MBO_ASSOC_DISALLOWED_AIR_INTERFACE_OVERLOADED);
6520 
6521         dumpProtoAndDeserialize();
6522 
6523         Int32Count[] expectedRecentFailureAssociationStatus = {
6524                 buildInt32Count(WifiConfiguration.RECENT_FAILURE_AP_UNABLE_TO_HANDLE_NEW_STA,
6525                         2),
6526                 buildInt32Count(
6527                         WifiConfiguration
6528                                 .RECENT_FAILURE_MBO_ASSOC_DISALLOWED_AIR_INTERFACE_OVERLOADED, 2),
6529                 buildInt32Count(
6530                         WifiConfiguration.RECENT_FAILURE_OCE_RSSI_BASED_ASSOCIATION_REJECTION, 1),
6531         };
6532 
6533         assertKeyCountsEqual(expectedRecentFailureAssociationStatus,
6534                 mDecodedProto.recentFailureAssociationStatus);
6535 
6536     }
6537 }
6538