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