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