• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wifi;
18 
19 import static android.net.wifi.WifiManager.EXTRA_PREVIOUS_WIFI_STATE;
20 import static android.net.wifi.WifiManager.EXTRA_WIFI_STATE;
21 import static android.net.wifi.WifiManager.WIFI_STATE_CHANGED_ACTION;
22 import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
23 import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
24 import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
25 import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING;
26 import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN;
27 
28 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
29 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY;
30 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SCAN_ONLY;
31 import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_TRANSIENT;
32 
33 import static org.junit.Assert.assertEquals;
34 import static org.junit.Assert.assertNotNull;
35 import static org.junit.Assert.assertNull;
36 import static org.junit.Assert.assertTrue;
37 import static org.mockito.Mockito.*;
38 import static org.mockito.Mockito.any;
39 import static org.mockito.Mockito.anyInt;
40 import static org.mockito.Mockito.doAnswer;
41 import static org.mockito.Mockito.lenient;
42 
43 import android.app.test.MockAnswerUtil.AnswerWithArguments;
44 import android.content.Context;
45 import android.content.Intent;
46 import android.net.ConnectivityManager;
47 import android.net.ConnectivityManager.NetworkCallback;
48 import android.net.NetworkRequest;
49 import android.net.wifi.IWifiConnectedNetworkScorer;
50 import android.net.wifi.WifiManager;
51 import android.os.Handler;
52 import android.os.IBinder;
53 import android.os.PersistableBundle;
54 import android.os.UserHandle;
55 import android.os.WorkSource;
56 import android.os.test.TestLooper;
57 import android.telephony.AccessNetworkConstants;
58 import android.telephony.CarrierConfigManager;
59 import android.telephony.SubscriptionInfo;
60 import android.telephony.SubscriptionManager;
61 import android.telephony.ims.ImsMmTelManager;
62 import android.telephony.ims.RegistrationManager;
63 import android.test.suitebuilder.annotation.SmallTest;
64 import android.util.Log;
65 
66 import com.android.server.wifi.ClientModeManagerBroadcastQueue.QueuedBroadcast;
67 import com.android.wifi.resources.R;
68 
69 import org.junit.After;
70 import org.junit.Before;
71 import org.junit.Test;
72 import org.mockito.ArgumentCaptor;
73 import org.mockito.InOrder;
74 import org.mockito.Mock;
75 import org.mockito.MockitoAnnotations;
76 import org.mockito.MockitoSession;
77 
78 import java.util.ArrayList;
79 import java.util.List;
80 import java.util.concurrent.Executor;
81 
82 /**
83  * Unit tests for {@link ConcreteClientModeManager}.
84  */
85 @SmallTest
86 public class ConcreteClientModeManagerTest extends WifiBaseTest {
87     private static final String TAG = "ClientModeManagerTest";
88     private static final String TEST_INTERFACE_NAME = "testif0";
89     private static final String OTHER_INTERFACE_NAME = "notTestIf";
90     private static final int TEST_WIFI_OFF_DEFERRING_TIME_MS = 4000;
91     private static final int TEST_ACTIVE_SUBSCRIPTION_ID = 1;
92     private static final WorkSource TEST_WORKSOURCE = new WorkSource();
93     private static final WorkSource TEST_WORKSOURCE2 = new WorkSource();
94 
95     TestLooper mLooper;
96 
97     ConcreteClientModeManager mClientModeManager;
98 
99     @Mock Context mContext;
100     @Mock WifiMetrics mWifiMetrics;
101     @Mock WifiNative mWifiNative;
102     @Mock Clock mClock;
103     @Mock ActiveModeManager.Listener<ConcreteClientModeManager> mListener;
104     @Mock WakeupController mWakeupController;
105     @Mock WifiInjector mWifiInjector;
106     @Mock DeviceConfigFacade mDeviceConfigFacade;
107     @Mock WifiDiagnostics mWifiDiagnostics;
108     @Mock ClientModeImpl mClientModeImpl;
109     @Mock CarrierConfigManager mCarrierConfigManager;
110     @Mock PersistableBundle mCarrierConfigBundle;
111     @Mock ImsMmTelManager mImsMmTelManager;
112     @Mock ConnectivityManager mConnectivityManager;
113     @Mock SubscriptionManager mSubscriptionManager;
114     @Mock SubscriptionInfo mActiveSubscriptionInfo;
115     @Mock SelfRecovery mSelfRecovery;
116     @Mock WifiGlobals mWifiGlobals;
117     @Mock ScanOnlyModeImpl mScanOnlyModeImpl;
118     @Mock DefaultClientModeManager mDefaultClientModeManager;
119     @Mock ClientModeManagerBroadcastQueue mBroadcastQueue;
120     @Mock ActiveModeWarden mActiveModeWarden;
121 
122     private RegistrationManager.RegistrationCallback mImsMmTelManagerRegistrationCallback = null;
123     private @RegistrationManager.ImsRegistrationState int mCurrentImsRegistrationState =
124             RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED;
125     private @AccessNetworkConstants.TransportType int mCurrentImsConnectionType =
126             AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
127     private NetworkRequest mImsRequest = null;
128     private NetworkCallback mImsNetworkCallback = null;
129     private long mElapsedSinceBootMillis = 0L;
130     private List<SubscriptionInfo> mSubscriptionInfoList = new ArrayList<>();
131     private MockResources mResources;
132 
133     private MockitoSession mStaticMockSession = null;
134 
135     final ArgumentCaptor<WifiNative.InterfaceCallback> mInterfaceCallbackCaptor =
136             ArgumentCaptor.forClass(WifiNative.InterfaceCallback.class);
137 
138     /**
139      * If mContext is reset, call it again to ensure system services could be retrieved
140      * from the context.
141      */
setUpSystemServiceForContext()142     private void setUpSystemServiceForContext() {
143         when(mContext.getSystemService(eq(CarrierConfigManager.class)))
144                 .thenReturn(mCarrierConfigManager);
145         when(mContext.getSystemService(eq(SubscriptionManager.class)))
146                 .thenReturn(mSubscriptionManager);
147         when(mContext.getSystemService(eq(ConnectivityManager.class)))
148                 .thenReturn(mConnectivityManager);
149         when(mContext.getResources()).thenReturn(mResources);
150         when(mWifiInjector.makeClientModeImpl(any(), any(), anyBoolean()))
151                 .thenReturn(mClientModeImpl);
152         when(mWifiInjector.makeScanOnlyModeImpl(any())).thenReturn(mScanOnlyModeImpl);
153     }
154 
155     /*
156      * Use this helper to move mock looper and clock together.
157      */
moveTimeForward(long timeMillis)158     private void moveTimeForward(long timeMillis) {
159         mLooper.moveTimeForward(timeMillis);
160         mElapsedSinceBootMillis += timeMillis;
161     }
162 
163 
164     @Before
setUp()165     public void setUp() throws Exception {
166         MockitoAnnotations.initMocks(this);
167 
168         // Prepare data
169         mResources = new MockResources();
170         mResources.setInteger(R.integer.config_wifiDelayDisconnectOnImsLostMs, 0);
171         mSubscriptionInfoList.add(mActiveSubscriptionInfo);
172 
173         setUpSystemServiceForContext();
174 
175         /**
176          * default mock for IMS deregistration:
177          * * No wifi calling
178          * * No network
179          * * no deferring time for wifi off
180          */
181         mStaticMockSession = mockitoSession()
182             .mockStatic(ImsMmTelManager.class)
183             .mockStatic(SubscriptionManager.class)
184             .startMocking();
185         lenient().when(ImsMmTelManager.createForSubscriptionId(eq(TEST_ACTIVE_SUBSCRIPTION_ID)))
186                 .thenReturn(mImsMmTelManager);
187         lenient().when(SubscriptionManager.isValidSubscriptionId(eq(TEST_ACTIVE_SUBSCRIPTION_ID)))
188                 .thenReturn(true);
189         doAnswer(new AnswerWithArguments() {
190             public void answer(Executor executor, RegistrationManager.RegistrationCallback c) {
191                 mImsMmTelManagerRegistrationCallback = c;
192                 // When the callback is registered, it will initiate the callback c to
193                 // be called with the current registration state.
194                 switch (mCurrentImsRegistrationState) {
195                     case RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED:
196                         c.onUnregistered(null);
197                         break;
198                     case RegistrationManager.REGISTRATION_STATE_REGISTERED:
199                         c.onRegistered(mCurrentImsConnectionType);
200                         break;
201                 }
202             }
203         }).when(mImsMmTelManager).registerImsRegistrationCallback(
204                 any(Executor.class),
205                 any(RegistrationManager.RegistrationCallback.class));
206         doAnswer(new AnswerWithArguments() {
207             public void answer(RegistrationManager.RegistrationCallback c) {
208                 if (mImsMmTelManagerRegistrationCallback == c) {
209                     mImsMmTelManagerRegistrationCallback = null;
210                 }
211             }
212         }).when(mImsMmTelManager).unregisterImsRegistrationCallback(
213                 any(RegistrationManager.RegistrationCallback.class));
214         when(mImsMmTelManager.isAvailable(anyInt(), anyInt())).thenReturn(false);
215 
216         when(mActiveSubscriptionInfo.getSubscriptionId()).thenReturn(TEST_ACTIVE_SUBSCRIPTION_ID);
217         when(mSubscriptionManager.getActiveSubscriptionInfoList())
218                 .thenReturn(mSubscriptionInfoList);
219         when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfigBundle);
220         when(mCarrierConfigBundle
221                 .getInt(eq(CarrierConfigManager.Ims.KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT)))
222                 .thenReturn(0);
223         doAnswer(new AnswerWithArguments() {
224             public void answer(NetworkRequest req, NetworkCallback callback, Handler handler) {
225                 mImsRequest = req;
226                 mImsNetworkCallback = callback;
227             }
228         }).when(mConnectivityManager).registerNetworkCallback(any(), any(), any());
229         doAnswer(new AnswerWithArguments() {
230             public void answer(NetworkCallback callback) {
231                 if (mImsNetworkCallback == callback) mImsNetworkCallback = null;
232             }
233         }).when(mConnectivityManager).unregisterNetworkCallback(any(NetworkCallback.class));
234         doAnswer(new AnswerWithArguments() {
235             public long answer() {
236                 return mElapsedSinceBootMillis;
237             }
238         }).when(mClock).getElapsedSinceBootMillis();
239         when(mWifiNative.replaceStaIfaceRequestorWs(TEST_INTERFACE_NAME, TEST_WORKSOURCE))
240                 .thenReturn(true);
241         doAnswer(new AnswerWithArguments() {
242             public void answer(ClientModeManager manager, QueuedBroadcast broadcast) {
243                 broadcast.send();
244             }
245         }).when(mBroadcastQueue).queueOrSendBroadcast(any(), any());
246         when(mDeviceConfigFacade.isInterfaceFailureBugreportEnabled()).thenReturn(true);
247         when(mWifiInjector.getDeviceConfigFacade()).thenReturn(mDeviceConfigFacade);
248         when(mWifiInjector.getWifiDiagnostics()).thenReturn(mWifiDiagnostics);
249         when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden);
250         mLooper = new TestLooper();
251     }
252 
253     @After
cleanUp()254     public void cleanUp() throws Exception {
255         mStaticMockSession.finishMocking();
256     }
257 
createClientModeManager(ActiveModeManager.ClientRole role)258     private ConcreteClientModeManager createClientModeManager(ActiveModeManager.ClientRole role) {
259         return new ConcreteClientModeManager(mContext, mLooper.getLooper(), mClock, mWifiNative,
260                 mListener, mWifiMetrics, mWakeupController, mWifiInjector, mSelfRecovery,
261                 mWifiGlobals, mDefaultClientModeManager, 0, TEST_WORKSOURCE, role,
262                 mBroadcastQueue, false);
263     }
264 
startClientInScanOnlyModeAndVerifyEnabled()265     private void startClientInScanOnlyModeAndVerifyEnabled() throws Exception {
266         when(mWifiNative.setupInterfaceForClientInScanMode(any(), any()))
267                 .thenReturn(TEST_INTERFACE_NAME);
268         mClientModeManager = createClientModeManager(ROLE_CLIENT_SCAN_ONLY);
269         mLooper.dispatchAll();
270 
271         verify(mWifiNative).setupInterfaceForClientInScanMode(
272                 mInterfaceCallbackCaptor.capture(), eq(TEST_WORKSOURCE));
273         verify(mWifiInjector, never()).makeClientModeImpl(any(), any(), anyBoolean());
274 
275         // now mark the interface as up
276         mInterfaceCallbackCaptor.getValue().onUp(TEST_INTERFACE_NAME);
277         mLooper.dispatchAll();
278 
279         // DeferStopHandler(): ConnectivityManager.class
280         verify(mContext).getSystemService(eq(ConnectivityManager.class));
281 
282         // Ensure that no public broadcasts were sent.
283         verifyNoMoreInteractions(mContext);
284         verify(mListener).onStarted(mClientModeManager);
285         verify(mWifiNative).setScanMode(TEST_INTERFACE_NAME, true);
286     }
287 
startClientInConnectModeAndVerifyEnabled()288     private void startClientInConnectModeAndVerifyEnabled() throws Exception {
289         when(mWifiNative.setupInterfaceForClientInScanMode(any(), any()))
290                 .thenReturn(TEST_INTERFACE_NAME);
291         when(mWifiNative.switchClientInterfaceToConnectivityMode(any(), any()))
292                 .thenReturn(true);
293         mClientModeManager = createClientModeManager(ROLE_CLIENT_PRIMARY);
294         mLooper.dispatchAll();
295 
296         verify(mWifiNative).setupInterfaceForClientInScanMode(
297                 mInterfaceCallbackCaptor.capture(), eq(TEST_WORKSOURCE));
298         verify(mWifiNative).switchClientInterfaceToConnectivityMode(
299                 TEST_INTERFACE_NAME, TEST_WORKSOURCE);
300         verify(mWifiInjector)
301                 .makeClientModeImpl(eq(TEST_INTERFACE_NAME), eq(mClientModeManager), anyBoolean());
302 
303         // now mark the interface as up
304         mInterfaceCallbackCaptor.getValue().onUp(TEST_INTERFACE_NAME);
305         mLooper.dispatchAll();
306 
307         verify(mClientModeImpl).onUpChanged(true);
308         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
309         verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(),
310                 eq(UserHandle.ALL));
311 
312         List<Intent> intents = intentCaptor.getAllValues();
313         assertEquals(2, intents.size());
314         Log.d(TAG, "captured intents: " + intents);
315         checkWifiConnectModeStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING,
316                 WIFI_STATE_DISABLED);
317         checkWifiConnectModeStateChangedBroadcast(intents.get(1), WIFI_STATE_ENABLED,
318                 WIFI_STATE_ENABLING);
319         verify(mActiveModeWarden).setWifiStateForApiCalls(WIFI_STATE_ENABLED);
320 
321         verify(mListener).onStarted(mClientModeManager);
322     }
323 
checkWifiConnectModeStateChangedBroadcast( Intent intent, int expectedCurrentState, int expectedPrevState)324     private void checkWifiConnectModeStateChangedBroadcast(
325             Intent intent, int expectedCurrentState, int expectedPrevState) {
326         String action = intent.getAction();
327         assertEquals(WIFI_STATE_CHANGED_ACTION, action);
328         int currentState = intent.getIntExtra(EXTRA_WIFI_STATE, WIFI_STATE_UNKNOWN);
329         assertEquals(expectedCurrentState, currentState);
330         int prevState = intent.getIntExtra(EXTRA_PREVIOUS_WIFI_STATE, WIFI_STATE_UNKNOWN);
331         assertEquals(expectedPrevState, prevState);
332     }
333 
verifyConnectModeNotificationsForCleanShutdown(int fromState)334     private void verifyConnectModeNotificationsForCleanShutdown(int fromState) {
335         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
336         verify(mContext, atLeastOnce())
337                 .sendStickyBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL));
338 
339         List<Intent> intents = intentCaptor.getAllValues();
340         assertTrue(intents.size() >= 2);
341         checkWifiConnectModeStateChangedBroadcast(intents.get(intents.size() - 2),
342                 WIFI_STATE_DISABLING, fromState);
343         checkWifiConnectModeStateChangedBroadcast(intents.get(intents.size() - 1),
344                 WIFI_STATE_DISABLED, WIFI_STATE_DISABLING);
345         verify(mActiveModeWarden).setWifiStateForApiCalls(WIFI_STATE_DISABLED);
346     }
347 
verifyConnectModeNotificationsForFailure()348     private void verifyConnectModeNotificationsForFailure() {
349         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
350         verify(mContext, atLeastOnce())
351                 .sendStickyBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL));
352 
353         List<Intent> intents = intentCaptor.getAllValues();
354         assertEquals(2, intents.size());
355         checkWifiConnectModeStateChangedBroadcast(intents.get(0), WIFI_STATE_DISABLING,
356                 WIFI_STATE_UNKNOWN);
357         checkWifiConnectModeStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED,
358                 WIFI_STATE_DISABLING);
359         verify(mActiveModeWarden).setWifiStateForApiCalls(WIFI_STATE_DISABLED);
360     }
361 
362     /**
363      * ClientMode start sets up an interface in ClientMode.
364      */
365     @Test
clientInConnectModeStartCreatesClientInterface()366     public void clientInConnectModeStartCreatesClientInterface() throws Exception {
367         startClientInConnectModeAndVerifyEnabled();
368     }
369 
370     /**
371      * ClientMode start sets up an interface in ClientMode.
372      */
373     @Test
clientInScanOnlyModeStartCreatesClientInterface()374     public void clientInScanOnlyModeStartCreatesClientInterface() throws Exception {
375         startClientInScanOnlyModeAndVerifyEnabled();
376 
377         mClientModeManager.getFactoryMacAddress();
378         // in scan only mode, should get value from ScanOnlyModeImpl
379         verify(mScanOnlyModeImpl).getFactoryMacAddress();
380     }
381 
382     /**
383      * Switch ClientModeManager from ScanOnly mode To Connect mode.
384      */
385     @Test
switchFromScanOnlyModeToConnectMode()386     public void switchFromScanOnlyModeToConnectMode() throws Exception {
387         startClientInScanOnlyModeAndVerifyEnabled();
388 
389         when(mWifiNative.switchClientInterfaceToConnectivityMode(any(), any()))
390                 .thenReturn(true);
391         mClientModeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY, TEST_WORKSOURCE);
392         mLooper.dispatchAll();
393 
394         verify(mWifiNative).setScanMode(TEST_INTERFACE_NAME, false);
395 
396         verify(mWifiInjector)
397                 .makeClientModeImpl(eq(TEST_INTERFACE_NAME), eq(mClientModeManager), anyBoolean());
398 
399         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
400         verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(),
401                 eq(UserHandle.ALL));
402 
403         List<Intent> intents = intentCaptor.getAllValues();
404         assertEquals(2, intents.size());
405         Log.d(TAG, "captured intents: " + intents);
406         checkWifiConnectModeStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING,
407                 WIFI_STATE_DISABLED);
408         checkWifiConnectModeStateChangedBroadcast(intents.get(1), WIFI_STATE_ENABLED,
409                 WIFI_STATE_ENABLING);
410         verify(mActiveModeWarden).setWifiStateForApiCalls(WIFI_STATE_ENABLED);
411 
412         verify(mListener).onStarted(mClientModeManager);
413         verify(mListener).onRoleChanged(mClientModeManager);
414 
415         mClientModeManager.getFactoryMacAddress();
416         // in client mode, should get value from ClientModeImpl
417         verify(mClientModeImpl).getFactoryMacAddress();
418     }
419 
420     /**
421      * Verify that no more public broadcasts are sent out after
422      * setWifiStateChangeBroadcastEnabled(false) is called.
423      */
424     @Test
testDisableWifiStateChangedBroadcasts()425     public void testDisableWifiStateChangedBroadcasts() throws Exception {
426         startClientInConnectModeAndVerifyEnabled();
427 
428         mClientModeManager.setWifiStateChangeBroadcastEnabled(false);
429         mClientModeManager.stop();
430         mLooper.dispatchAll();
431 
432         verify(mClientModeImpl).stop();
433         verify(mActiveModeWarden, never()).setWifiStateForApiCalls(WIFI_STATE_DISABLED);
434 
435         // Ensure that only public broadcasts for the "start" events were sent.
436         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
437         verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(),
438                 eq(UserHandle.ALL));
439 
440         List<Intent> intents = intentCaptor.getAllValues();
441         assertEquals(2, intents.size());
442         Log.d(TAG, "captured intents: " + intents);
443         checkWifiConnectModeStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING,
444                 WIFI_STATE_DISABLED);
445         checkWifiConnectModeStateChangedBroadcast(intents.get(1), WIFI_STATE_ENABLED,
446                 WIFI_STATE_ENABLING);
447     }
448 
449     /**
450      * Switch ClientModeManager from Connect mode to ScanOnly mode.
451      */
452     @Test
switchFromConnectModeToScanOnlyMode()453     public void switchFromConnectModeToScanOnlyMode() throws Exception {
454         startClientInConnectModeAndVerifyEnabled();
455 
456         when(mWifiNative.switchClientInterfaceToScanMode(any(), any()))
457                 .thenReturn(true);
458         mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE);
459         mLooper.dispatchAll();
460 
461         verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
462         verify(mWifiNative).setupInterfaceForClientInScanMode(
463                 mInterfaceCallbackCaptor.capture(), eq(TEST_WORKSOURCE));
464         verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE);
465         verify(mClientModeImpl).stop();
466 
467         // DeferStopHandler(): ConnectivityManager.class
468         // getWifiOffDeferringTimeMs(): SubscriptionManager.class
469         verify(mContext).getSystemService(eq(ConnectivityManager.class));
470         verify(mContext).getSystemService(eq(SubscriptionManager.class));
471         verify(mImsMmTelManager, never()).registerImsRegistrationCallback(any(), any());
472         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
473 
474         // Ensure that no public broadcasts were sent.
475         verifyNoMoreInteractions(mContext);
476         verify(mListener).onStarted(mClientModeManager);
477         verify(mListener).onRoleChanged(mClientModeManager);
478     }
479 
480     /**
481      * ClientMode increments failure metrics when failing to setup client mode in connectivity mode.
482      */
483     @Test
detectAndReportErrorWhenSetupForClientInConnectivityModeWifiNativeFailure()484     public void detectAndReportErrorWhenSetupForClientInConnectivityModeWifiNativeFailure()
485             throws Exception {
486         when(mWifiNative.setupInterfaceForClientInScanMode(any(), any()))
487                 .thenReturn(TEST_INTERFACE_NAME);
488         when(mWifiNative.switchClientInterfaceToConnectivityMode(any(), any())).thenReturn(false);
489 
490         mClientModeManager = createClientModeManager(ROLE_CLIENT_PRIMARY);
491         mLooper.dispatchAll();
492 
493         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
494         verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(),
495                 eq(UserHandle.ALL));
496         List<Intent> intents = intentCaptor.getAllValues();
497         assertEquals(2, intents.size());
498         checkWifiConnectModeStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING,
499                 WIFI_STATE_DISABLED);
500         checkWifiConnectModeStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED,
501                 WIFI_STATE_UNKNOWN);
502         verify(mActiveModeWarden).setWifiStateForApiCalls(WIFI_STATE_DISABLED);
503         verify(mListener).onStartFailure(mClientModeManager);
504         verify(mWifiDiagnostics).takeBugReport(anyString(), anyString());
505     }
506 
507     /** Tests failure when setting up iface for scan only mode. */
508     @Test
detectAndReportErrorWhenSetupInterfaceForClientInScanModeWifiNativeFailure()509     public void detectAndReportErrorWhenSetupInterfaceForClientInScanModeWifiNativeFailure()
510             throws Exception {
511         // failed to setup iface in Scan Only mode
512         when(mWifiNative.setupInterfaceForClientInScanMode(any(), any())).thenReturn(null);
513 
514         mClientModeManager = createClientModeManager(ROLE_CLIENT_PRIMARY);
515         mLooper.dispatchAll();
516 
517         verify(mActiveModeWarden, never()).setWifiStateForApiCalls(anyInt());
518         verify(mListener).onStartFailure(mClientModeManager);
519         verify(mWifiDiagnostics).takeBugReport(anyString(), anyString());
520 
521         mClientModeManager.getFactoryMacAddress();
522         // wifi is off, should get value from DefaultClientModeManager
523         verify(mDefaultClientModeManager).getFactoryMacAddress();
524     }
525 
526     /**
527      * ClientMode stop before start has been processed properly cleans up state & invokes the
528      * onStopped callback.
529      */
530     @Test
clientModeStopBeforeStartCleansUpState()531     public void clientModeStopBeforeStartCleansUpState() throws Exception {
532         mClientModeManager = createClientModeManager(ROLE_CLIENT_PRIMARY);
533         // Invoke stop before the internal start is processed by the state machine.
534         mClientModeManager.stop();
535         mLooper.dispatchAll();
536         when(mClientModeImpl.hasQuit()).thenReturn(true);
537         mClientModeManager.onClientModeImplQuit();
538         verify(mListener).onStopped(mClientModeManager);
539 
540         // Don't initiate wifi native setup.
541         verifyNoMoreInteractions(mListener, mWifiNative);
542         assertNull(mClientModeManager.getRole());
543         assertNull(mClientModeManager.getPreviousRole());
544     }
545 
546     /**
547      * ClientMode stop properly cleans up state & invokes the onStopped callback.
548      */
549     @Test
clientModeStopCleansUpState()550     public void clientModeStopCleansUpState() throws Exception {
551         startClientInConnectModeAndVerifyEnabled();
552         reset(mContext, mListener);
553         setUpSystemServiceForContext();
554         mClientModeManager.stop();
555         mLooper.dispatchAll();
556         // role has not been reset yet
557         ActiveModeManager.ClientRole lastRole = mClientModeManager.getRole();
558         assertNotNull(lastRole);
559         assertNull(mClientModeManager.getPreviousRole());
560 
561         long testChangeRoleTimestamp = 12234455L;
562         when(mClock.getElapsedSinceBootMillis()).thenReturn(testChangeRoleTimestamp);
563         when(mClientModeImpl.hasQuit()).thenReturn(true);
564         mClientModeManager.onClientModeImplQuit();
565         verify(mListener).onStopped(mClientModeManager);
566 
567         // then role will be reset
568         assertNull(mClientModeManager.getRole());
569         assertEquals("Should equal previous role", lastRole,
570                 mClientModeManager.getPreviousRole());
571         assertEquals("The role change timestamp should match", testChangeRoleTimestamp,
572                 mClientModeManager.getLastRoleChangeSinceBootMs());
573 
574         verify(mImsMmTelManager, never()).registerImsRegistrationCallback(any(), any());
575         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
576 
577         verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
578 
579         // on an explicit stop, we should not trigger the callback
580         verifyNoMoreInteractions(mListener);
581     }
582 
583     /**
584      * Triggering interface down when ClientMode is active properly exits the active state.
585      */
586     @Test
clientModeStartedStopsWhenInterfaceDown()587     public void clientModeStartedStopsWhenInterfaceDown() throws Exception {
588         startClientInConnectModeAndVerifyEnabled();
589         reset(mContext);
590         setUpSystemServiceForContext();
591         when(mWifiGlobals.isConnectedMacRandomizationEnabled()).thenReturn(false);
592         mInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME);
593         mLooper.dispatchAll();
594         verify(mSelfRecovery).trigger(SelfRecovery.REASON_STA_IFACE_DOWN);
595         verifyConnectModeNotificationsForFailure();
596         when(mClientModeImpl.hasQuit()).thenReturn(true);
597         mClientModeManager.onClientModeImplQuit();
598         verify(mListener).onStopped(mClientModeManager);
599     }
600 
601     /**
602      * Triggering interface down when ClientMode is active and Connected MacRandomization is enabled
603      * does not exit the active state.
604      */
605     @Test
clientModeStartedWithConnectedMacRandDoesNotStopWhenInterfaceDown()606     public void clientModeStartedWithConnectedMacRandDoesNotStopWhenInterfaceDown()
607             throws Exception {
608         startClientInConnectModeAndVerifyEnabled();
609         reset(mContext);
610         setUpSystemServiceForContext();
611         when(mWifiGlobals.isConnectedMacRandomizationEnabled()).thenReturn(true);
612         mInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME);
613         mLooper.dispatchAll();
614         verify(mSelfRecovery, never()).trigger(SelfRecovery.REASON_STA_IFACE_DOWN);
615         verify(mContext, never()).sendStickyBroadcastAsUser(any(), any());
616     }
617 
618     /**
619      * Testing the handling of an interface destroyed notification.
620      */
621     @Test
clientModeStartedStopsOnInterfaceDestroyed()622     public void clientModeStartedStopsOnInterfaceDestroyed() throws Exception {
623         startClientInConnectModeAndVerifyEnabled();
624         reset(mContext);
625         setUpSystemServiceForContext();
626         mInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME);
627         mLooper.dispatchAll();
628         verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
629         verify(mClientModeImpl).handleIfaceDestroyed();
630         when(mClientModeImpl.hasQuit()).thenReturn(true);
631         mClientModeManager.onClientModeImplQuit();
632         verify(mListener).onStopped(mClientModeManager);
633     }
634 
635     /**
636      * Verify that onDestroyed after client mode is stopped doesn't trigger a callback.
637      */
638     @Test
noCallbackOnInterfaceDestroyedWhenAlreadyStopped()639     public void noCallbackOnInterfaceDestroyedWhenAlreadyStopped() throws Exception {
640         startClientInConnectModeAndVerifyEnabled();
641 
642         reset(mListener);
643 
644         mClientModeManager.stop();
645         mLooper.dispatchAll();
646 
647         // now trigger interface destroyed and make sure callback doesn't get called
648         mInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME);
649         mLooper.dispatchAll();
650         when(mClientModeImpl.hasQuit()).thenReturn(true);
651         mClientModeManager.onClientModeImplQuit();
652         verify(mListener).onStopped(mClientModeManager);
653 
654         verifyNoMoreInteractions(mListener);
655         verify(mClientModeImpl, never()).handleIfaceDestroyed();
656     }
657 
658     /**
659      * Entering ScanOnly state starts the WakeupController.
660      */
661     @Test
scanModeEnterStartsWakeupController()662     public void scanModeEnterStartsWakeupController() throws Exception {
663         startClientInScanOnlyModeAndVerifyEnabled();
664 
665         verify(mWakeupController).start();
666     }
667 
668     /**
669      * Exiting ScanOnly state stops the WakeupController.
670      */
671     @Test
scanModeExitStopsWakeupController()672     public void scanModeExitStopsWakeupController() throws Exception {
673         startClientInScanOnlyModeAndVerifyEnabled();
674 
675         mClientModeManager.stop();
676         mLooper.dispatchAll();
677 
678         assertNull(mClientModeManager.getRole());
679 
680         InOrder inOrder = inOrder(mWakeupController, mWifiNative, mListener);
681 
682         inOrder.verify(mListener).onStarted(mClientModeManager);
683         inOrder.verify(mWakeupController).start();
684         inOrder.verify(mWakeupController).stop();
685         inOrder.verify(mWifiNative).teardownInterface(eq(TEST_INTERFACE_NAME));
686     }
687 
setUpVoWifiTest( boolean isWifiCallingAvailable, int wifiOffDeferringTimeMs)688     private void setUpVoWifiTest(
689             boolean isWifiCallingAvailable,
690             int wifiOffDeferringTimeMs) {
691         mCurrentImsRegistrationState = (isWifiCallingAvailable)
692             ? RegistrationManager.REGISTRATION_STATE_REGISTERED
693             : RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED;
694         mCurrentImsConnectionType = (isWifiCallingAvailable)
695             ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
696             : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
697         when(mImsMmTelManager.isAvailable(anyInt(), anyInt())).thenReturn(isWifiCallingAvailable);
698         when(mCarrierConfigBundle
699                 .getInt(eq(CarrierConfigManager.Ims.KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT)))
700                 .thenReturn(wifiOffDeferringTimeMs);
701     }
702 
703     /**
704      * ClientMode stop properly with IMS deferring time without WifiCalling.
705      */
706     @Test
clientModeStopWithWifiOffDeferringTimeNoWifiCalling()707     public void clientModeStopWithWifiOffDeferringTimeNoWifiCalling() throws Exception {
708         setUpVoWifiTest(false,
709                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
710 
711         startClientInConnectModeAndVerifyEnabled();
712         reset(mContext, mListener);
713         setUpSystemServiceForContext();
714         mClientModeManager.stop();
715         mLooper.dispatchAll();
716         when(mClientModeImpl.hasQuit()).thenReturn(true);
717         mClientModeManager.onClientModeImplQuit();
718         verify(mListener).onStopped(mClientModeManager);
719 
720         verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
721 
722         verify(mImsMmTelManager, never()).registerImsRegistrationCallback(any(), any());
723         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
724         verify(mWifiMetrics).noteWifiOff(eq(false), eq(false), anyInt());
725 
726         // on an explicit stop, we should not trigger the callback
727         verifyNoMoreInteractions(mListener);
728     }
729 
730     /**
731      * ClientMode stop properly with IMS deferring time and IMS is registered on WWAN.
732      */
733     @Test
clientModeStopWithWifiOffDeferringTimeAndImsOnWwan()734     public void clientModeStopWithWifiOffDeferringTimeAndImsOnWwan() throws Exception {
735         setUpVoWifiTest(true,
736                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
737         mCurrentImsConnectionType = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
738 
739         startClientInConnectModeAndVerifyEnabled();
740         reset(mContext, mListener);
741         setUpSystemServiceForContext();
742         mClientModeManager.stop();
743         mLooper.dispatchAll();
744         when(mClientModeImpl.hasQuit()).thenReturn(true);
745         mClientModeManager.onClientModeImplQuit();
746         verify(mListener).onStopped(mClientModeManager);
747 
748         verify(mImsMmTelManager).registerImsRegistrationCallback(
749                 any(Executor.class),
750                 any(RegistrationManager.RegistrationCallback.class));
751         verify(mImsMmTelManager).unregisterImsRegistrationCallback(
752                 any(RegistrationManager.RegistrationCallback.class));
753         assertNull(mImsMmTelManagerRegistrationCallback);
754         verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt());
755 
756         verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
757 
758         // on an explicit stop, we should not trigger the callback
759         verifyNoMoreInteractions(mListener);
760     }
761 
762     /**
763      * ClientMode stop properly with IMS deferring time, Wifi calling.
764      */
765     @Test
clientModeStopWithWifiOffDeferringTimeWithWifiCalling()766     public void clientModeStopWithWifiOffDeferringTimeWithWifiCalling() throws Exception {
767         setUpVoWifiTest(true,
768                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
769 
770         startClientInConnectModeAndVerifyEnabled();
771         reset(mContext, mListener);
772         setUpSystemServiceForContext();
773         mClientModeManager.stop();
774         mLooper.dispatchAll();
775         mImsNetworkCallback.onAvailable(null);
776         mLooper.dispatchAll();
777 
778         // Not yet finish IMS deregistration.
779         verify(mImsMmTelManager).registerImsRegistrationCallback(
780                 any(Executor.class),
781                 any(RegistrationManager.RegistrationCallback.class));
782         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
783         verify(mListener, never()).onStopped(any());
784         verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt());
785 
786         // Notify wifi service IMS service is de-registered.
787         assertNotNull(mImsMmTelManagerRegistrationCallback);
788         mImsMmTelManagerRegistrationCallback.onUnregistered(null);
789         assertNotNull(mImsNetworkCallback);
790         mImsNetworkCallback.onLost(null);
791         mLooper.dispatchAll();
792 
793         // Now Wifi could be turned off actually.
794         verify(mImsMmTelManager).unregisterImsRegistrationCallback(
795                 any(RegistrationManager.RegistrationCallback.class));
796         assertNull(mImsMmTelManagerRegistrationCallback);
797         assertNull(mImsNetworkCallback);
798         when(mClientModeImpl.hasQuit()).thenReturn(true);
799         mClientModeManager.onClientModeImplQuit();
800         verify(mListener).onStopped(mClientModeManager);
801         verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt());
802 
803         verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
804 
805         // on an explicit stop, we should not trigger the callback
806         verifyNoMoreInteractions(mListener);
807     }
808 
809     /**
810      * ClientMode stop properly with IMS deferring time, Wifi calling.
811      *
812      * The network losts first and then IMS is de-registered.
813      * The WIFI should be off after IMS deregistration.
814      */
815     @Test
clientModeStopWithWifiOffDeferringTimeWithWifiCallingAndNetworkLostFirst()816     public void clientModeStopWithWifiOffDeferringTimeWithWifiCallingAndNetworkLostFirst()
817             throws Exception {
818         setUpVoWifiTest(true,
819                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
820 
821         startClientInConnectModeAndVerifyEnabled();
822         reset(mContext, mListener);
823         setUpSystemServiceForContext();
824         mClientModeManager.stop();
825         mLooper.dispatchAll();
826         mImsNetworkCallback.onAvailable(null);
827         mLooper.dispatchAll();
828 
829         // Not yet finish IMS deregistration.
830         verify(mImsMmTelManager).registerImsRegistrationCallback(
831                 any(Executor.class),
832                 any(RegistrationManager.RegistrationCallback.class));
833         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
834         when(mClientModeImpl.hasQuit()).thenReturn(true);
835         mClientModeManager.onClientModeImplQuit();
836         verify(mListener, never()).onStopped(any());
837         verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt());
838 
839         // Notify wifi service the network lost.
840         assertNotNull(mImsNetworkCallback);
841         mImsNetworkCallback.onLost(null);
842         mLooper.dispatchAll();
843 
844         // Since IMS service is not de-registered yet, wifi should be available.
845         moveTimeForward(1000);
846         mLooper.dispatchAll();
847         verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any());
848         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
849         verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt());
850 
851         // Notify wifi service IMS service is de-registered.
852         assertNotNull(mImsMmTelManagerRegistrationCallback);
853         mImsMmTelManagerRegistrationCallback.onUnregistered(null);
854         mLooper.dispatchAll();
855 
856         // Now Wifi could be turned off actually.
857         verify(mImsMmTelManager).unregisterImsRegistrationCallback(
858                 any(RegistrationManager.RegistrationCallback.class));
859         assertNull(mImsMmTelManagerRegistrationCallback);
860         assertNull(mImsNetworkCallback);
861         when(mClientModeImpl.hasQuit()).thenReturn(true);
862         mClientModeManager.onClientModeImplQuit();
863         verify(mListener).onStopped(mClientModeManager);
864         verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt());
865 
866         verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
867 
868         // on an explicit stop, we should not trigger the callback
869         verifyNoMoreInteractions(mListener);
870     }
871 
872     /**
873      * ClientMode stop properly with IMS deferring time and Wifi calling.
874      *
875      * IMS deregistration is done before reaching the timeout.
876      */
877     @Test
clientModeStopWithWifiOffDeferringTimeAndWifiCallingOnImsRegistered()878     public void clientModeStopWithWifiOffDeferringTimeAndWifiCallingOnImsRegistered()
879             throws Exception {
880         setUpVoWifiTest(true,
881                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
882 
883         startClientInConnectModeAndVerifyEnabled();
884         reset(mContext, mListener);
885         setUpSystemServiceForContext();
886         mClientModeManager.stop();
887         mLooper.dispatchAll();
888 
889         // Not yet finish IMS deregistration.
890         verify(mImsMmTelManager).registerImsRegistrationCallback(
891                 any(Executor.class),
892                 any(RegistrationManager.RegistrationCallback.class));
893         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
894         when(mClientModeImpl.hasQuit()).thenReturn(true);
895         mClientModeManager.onClientModeImplQuit();
896         verify(mListener, never()).onStopped(any());
897         verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt());
898 
899         // Notify wifi service IMS service is de-registered.
900         assertNotNull(mImsMmTelManagerRegistrationCallback);
901         mImsMmTelManagerRegistrationCallback.onRegistered(0);
902         mLooper.dispatchAll();
903 
904         // Now Wifi could be turned off actually.
905         verify(mImsMmTelManager).unregisterImsRegistrationCallback(
906                 any(RegistrationManager.RegistrationCallback.class));
907         assertNull(mImsMmTelManagerRegistrationCallback);
908         when(mClientModeImpl.hasQuit()).thenReturn(true);
909         mClientModeManager.onClientModeImplQuit();
910         verify(mListener).onStopped(mClientModeManager);
911         verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt());
912 
913         verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
914 
915         // on an explicit stop, we should not trigger the callback
916         verifyNoMoreInteractions(mListener);
917     }
918 
919     /**
920      * ClientMode stop properly with IMS deferring time and Wifi calling.
921      *
922      * IMS deregistration is NOT done before reaching the timeout.
923      */
924     @Test
clientModeStopWithWifiOffDeferringTimeAndWifiCallingTimedOut()925     public void clientModeStopWithWifiOffDeferringTimeAndWifiCallingTimedOut()
926             throws Exception {
927         setUpVoWifiTest(true,
928                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
929 
930         startClientInConnectModeAndVerifyEnabled();
931         reset(mContext, mListener);
932         setUpSystemServiceForContext();
933         mClientModeManager.stop();
934         mLooper.dispatchAll();
935         verify(mImsMmTelManager).registerImsRegistrationCallback(
936                 any(Executor.class),
937                 any(RegistrationManager.RegistrationCallback.class));
938         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
939         when(mClientModeImpl.hasQuit()).thenReturn(true);
940         mClientModeManager.onClientModeImplQuit();
941         verify(mListener, never()).onStopped(any());
942 
943         // 1/2 deferring time passed, should be still waiting for the callback.
944         moveTimeForward(TEST_WIFI_OFF_DEFERRING_TIME_MS / 2);
945         mLooper.dispatchAll();
946         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
947         verify(mListener, never()).onStopped(any());
948         verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt());
949 
950         // Exceeding the timeout, wifi should be stopped.
951         moveTimeForward(TEST_WIFI_OFF_DEFERRING_TIME_MS / 2 + 1000);
952         mLooper.dispatchAll();
953         verify(mImsMmTelManager).unregisterImsRegistrationCallback(
954                 any(RegistrationManager.RegistrationCallback.class));
955         assertNull(mImsMmTelManagerRegistrationCallback);
956         when(mClientModeImpl.hasQuit()).thenReturn(true);
957         mClientModeManager.onClientModeImplQuit();
958         verify(mListener).onStopped(mClientModeManager);
959         verify(mWifiMetrics).noteWifiOff(eq(true), eq(true), anyInt());
960 
961         verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
962 
963         // on an explicit stop, we should not trigger the callback
964         verifyNoMoreInteractions(mListener);
965     }
966 
967     /**
968      * ClientMode stop properly with IMS deferring time and Wifi calling.
969      *
970      * IMS deregistration is NOT done before reaching the timeout with multiple stop calls.
971      */
972     @Test
clientModeStopWithWifiOffDeferringTimeAndWifiCallingTimedOutMultipleStop()973     public void clientModeStopWithWifiOffDeferringTimeAndWifiCallingTimedOutMultipleStop()
974             throws Exception {
975         setUpVoWifiTest(true,
976                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
977 
978         startClientInConnectModeAndVerifyEnabled();
979         reset(mContext, mListener);
980         setUpSystemServiceForContext();
981         mClientModeManager.stop();
982         mLooper.dispatchAll();
983         verify(mImsMmTelManager).registerImsRegistrationCallback(
984                 any(Executor.class),
985                 any(RegistrationManager.RegistrationCallback.class));
986         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
987         verify(mListener, never()).onStopped(any());
988 
989         mClientModeManager.stop();
990         mLooper.dispatchAll();
991         // should not register another listener.
992         verify(mImsMmTelManager, times(1)).registerImsRegistrationCallback(
993                 any(Executor.class),
994                 any(RegistrationManager.RegistrationCallback.class));
995         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
996         verify(mListener, never()).onStopped(any());
997         verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt());
998 
999         // Exceeding the timeout, wifi should be stopped.
1000         moveTimeForward(TEST_WIFI_OFF_DEFERRING_TIME_MS + 1000);
1001         mLooper.dispatchAll();
1002         verify(mImsMmTelManager).unregisterImsRegistrationCallback(
1003                 any(RegistrationManager.RegistrationCallback.class));
1004         assertNull(mImsMmTelManagerRegistrationCallback);
1005         when(mClientModeImpl.hasQuit()).thenReturn(true);
1006         mClientModeManager.onClientModeImplQuit();
1007         verify(mListener).onStopped(mClientModeManager);
1008         verify(mWifiMetrics).noteWifiOff(eq(true), eq(true), anyInt());
1009 
1010         verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
1011 
1012         // on an explicit stop, we should not trigger the callback
1013         verifyNoMoreInteractions(mListener);
1014     }
1015 
1016     /**
1017      * Switch to scan mode properly with IMS deferring time without WifiCalling.
1018      */
1019     @Test
switchToScanOnlyModeWithWifiOffDeferringTimeNoWifiCalling()1020     public void switchToScanOnlyModeWithWifiOffDeferringTimeNoWifiCalling() throws Exception {
1021         setUpVoWifiTest(false,
1022                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
1023 
1024         startClientInConnectModeAndVerifyEnabled();
1025         reset(mContext, mListener);
1026         setUpSystemServiceForContext();
1027         when(mWifiNative.switchClientInterfaceToScanMode(any(), any()))
1028                 .thenReturn(true);
1029 
1030         mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE);
1031         mLooper.dispatchAll();
1032 
1033         verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE);
1034         verify(mImsMmTelManager, never()).registerImsRegistrationCallback(any(), any());
1035         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
1036         verify(mWifiMetrics).noteWifiOff(eq(false), eq(false), anyInt());
1037     }
1038 
1039     /**
1040      * Switch to scan mode properly with IMS deferring time and IMS is registered on WWAN.
1041      */
1042     @Test
switchToScanOnlyModeWithWifiOffDeferringTimeAndImsOnWwan()1043     public void switchToScanOnlyModeWithWifiOffDeferringTimeAndImsOnWwan() throws Exception {
1044         setUpVoWifiTest(true,
1045                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
1046         mCurrentImsConnectionType = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
1047 
1048         startClientInConnectModeAndVerifyEnabled();
1049         reset(mContext, mListener);
1050         setUpSystemServiceForContext();
1051         when(mWifiNative.switchClientInterfaceToScanMode(any(), any()))
1052                 .thenReturn(true);
1053 
1054         mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE);
1055         mLooper.dispatchAll();
1056 
1057         verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE);
1058 
1059         verify(mImsMmTelManager).registerImsRegistrationCallback(
1060                 any(Executor.class),
1061                 any(RegistrationManager.RegistrationCallback.class));
1062         verify(mImsMmTelManager).unregisterImsRegistrationCallback(
1063                 any(RegistrationManager.RegistrationCallback.class));
1064         assertNull(mImsMmTelManagerRegistrationCallback);
1065         verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt());
1066     }
1067 
1068     /**
1069      * Switch to scan mode properly with IMS deferring time and Wifi calling.
1070      *
1071      * IMS deregistration is done before reaching the timeout.
1072      */
1073     @Test
switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingOnImsUnregistered()1074     public void switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingOnImsUnregistered()
1075             throws Exception {
1076         setUpVoWifiTest(true,
1077                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
1078 
1079         startClientInConnectModeAndVerifyEnabled();
1080         reset(mContext, mListener);
1081         setUpSystemServiceForContext();
1082         when(mWifiNative.switchClientInterfaceToScanMode(any(), any()))
1083                 .thenReturn(true);
1084 
1085         mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE);
1086         mLooper.dispatchAll();
1087         mImsNetworkCallback.onAvailable(null);
1088         mLooper.dispatchAll();
1089 
1090         // Not yet finish IMS deregistration.
1091         verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any());
1092         verify(mImsMmTelManager).registerImsRegistrationCallback(
1093                 any(Executor.class),
1094                 any(RegistrationManager.RegistrationCallback.class));
1095         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
1096         verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt());
1097 
1098         // Notify wifi service IMS service is de-registered.
1099         assertNotNull(mImsMmTelManagerRegistrationCallback);
1100         mImsMmTelManagerRegistrationCallback.onUnregistered(null);
1101         assertNotNull(mImsNetworkCallback);
1102         mImsNetworkCallback.onLost(null);
1103         mLooper.dispatchAll();
1104 
1105         // Now Wifi could be switched to scan mode actually.
1106         verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE);
1107         verify(mImsMmTelManager).unregisterImsRegistrationCallback(
1108                 any(RegistrationManager.RegistrationCallback.class));
1109         assertNull(mImsMmTelManagerRegistrationCallback);
1110         assertNull(mImsNetworkCallback);
1111         verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt());
1112     }
1113 
1114     /**
1115      * Switch to scan mode properly with IMS deferring time and Wifi calling.
1116      *
1117      * Network lost before IMS deregistration is done. The wifi should be still available
1118      * until IMS is de-registered or time out.
1119      */
1120     @Test
switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingOnNetworkLostFirst()1121     public void switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingOnNetworkLostFirst()
1122             throws Exception {
1123         setUpVoWifiTest(true,
1124                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
1125 
1126         startClientInConnectModeAndVerifyEnabled();
1127         reset(mContext, mListener);
1128         setUpSystemServiceForContext();
1129         when(mWifiNative.switchClientInterfaceToScanMode(any(), any()))
1130                 .thenReturn(true);
1131 
1132         mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE);
1133         mLooper.dispatchAll();
1134         mImsNetworkCallback.onAvailable(null);
1135         mLooper.dispatchAll();
1136 
1137         // Not yet finish IMS deregistration.
1138         verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any());
1139         verify(mImsMmTelManager).registerImsRegistrationCallback(
1140                 any(Executor.class),
1141                 any(RegistrationManager.RegistrationCallback.class));
1142         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
1143         verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt());
1144 
1145         // Notify wifi service network lost
1146         assertNotNull(mImsNetworkCallback);
1147         mImsNetworkCallback.onLost(null);
1148         mLooper.dispatchAll();
1149 
1150         // Since IMS service is not de-registered yet, wifi should be available.
1151         moveTimeForward(1000);
1152         mLooper.dispatchAll();
1153         verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any());
1154         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
1155         verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt());
1156 
1157         // Notify wifi service IMS service is de-registered.
1158         assertNotNull(mImsMmTelManagerRegistrationCallback);
1159         mImsMmTelManagerRegistrationCallback.onUnregistered(null);
1160         mLooper.dispatchAll();
1161 
1162         // Now Wifi could be switched to scan mode actually.
1163         verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE);
1164         verify(mImsMmTelManager).unregisterImsRegistrationCallback(
1165                 any(RegistrationManager.RegistrationCallback.class));
1166         assertNull(mImsMmTelManagerRegistrationCallback);
1167         assertNull(mImsNetworkCallback);
1168         verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt());
1169     }
1170 
1171     /**
1172      * Switch to scan mode properly with IMS deferring time and Wifi calling.
1173      *
1174      * IMS deregistration is done before reaching the timeout.
1175      */
1176     @Test
switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingOnImsRegistered()1177     public void switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingOnImsRegistered()
1178             throws Exception {
1179         setUpVoWifiTest(true,
1180                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
1181 
1182         startClientInConnectModeAndVerifyEnabled();
1183         reset(mContext, mListener);
1184         setUpSystemServiceForContext();
1185         when(mWifiNative.switchClientInterfaceToScanMode(any(), any()))
1186                 .thenReturn(true);
1187 
1188         mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE);
1189         mLooper.dispatchAll();
1190 
1191         // Not yet finish IMS deregistration.
1192         verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any());
1193         verify(mImsMmTelManager).registerImsRegistrationCallback(
1194                 any(Executor.class),
1195                 any(RegistrationManager.RegistrationCallback.class));
1196         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
1197         verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt());
1198 
1199         // Notify wifi service IMS service is de-registered.
1200         assertNotNull(mImsMmTelManagerRegistrationCallback);
1201         mImsMmTelManagerRegistrationCallback.onRegistered(0);
1202         mLooper.dispatchAll();
1203 
1204         // Now Wifi could be switched to scan mode actually.
1205         verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE);
1206         verify(mImsMmTelManager).unregisterImsRegistrationCallback(
1207                 any(RegistrationManager.RegistrationCallback.class));
1208         assertNull(mImsMmTelManagerRegistrationCallback);
1209         verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt());
1210     }
1211 
1212     /**
1213      * Switch to scan mode properly with IMS deferring time and Wifi calling.
1214      *
1215      * IMS deregistration is NOT done before reaching the timeout.
1216      */
1217     @Test
switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingTimedOut()1218     public void switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingTimedOut()
1219             throws Exception {
1220         setUpVoWifiTest(true,
1221                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
1222 
1223         startClientInConnectModeAndVerifyEnabled();
1224         reset(mContext, mListener);
1225         setUpSystemServiceForContext();
1226         when(mWifiNative.switchClientInterfaceToScanMode(any(), any()))
1227                 .thenReturn(true);
1228 
1229         mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE);
1230         mLooper.dispatchAll();
1231 
1232         verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any());
1233         verify(mImsMmTelManager).registerImsRegistrationCallback(
1234                 any(Executor.class),
1235                 any(RegistrationManager.RegistrationCallback.class));
1236         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
1237 
1238         // 1/2 deferring time passed, should be still waiting for the callback.
1239         moveTimeForward(TEST_WIFI_OFF_DEFERRING_TIME_MS / 2);
1240         mLooper.dispatchAll();
1241         verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any());
1242         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
1243         verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt());
1244 
1245         // Exceeding the timeout, wifi should be stopped.
1246         moveTimeForward(TEST_WIFI_OFF_DEFERRING_TIME_MS / 2 + 1000);
1247         mLooper.dispatchAll();
1248         verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE);
1249         verify(mImsMmTelManager).unregisterImsRegistrationCallback(
1250                 any(RegistrationManager.RegistrationCallback.class));
1251         assertNull(mImsMmTelManagerRegistrationCallback);
1252         verify(mWifiMetrics).noteWifiOff(eq(true), eq(true), anyInt());
1253     }
1254 
1255     /**
1256      * Switch to scan mode properly with IMS deferring time and Wifi calling.
1257      *
1258      * IMS deregistration is NOT done before reaching the timeout with multiple stop calls.
1259      */
1260     @Test
1261     public void
switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingTimedOutMultipleSwitch()1262             switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingTimedOutMultipleSwitch()
1263             throws Exception {
1264         setUpVoWifiTest(true,
1265                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
1266 
1267         startClientInConnectModeAndVerifyEnabled();
1268         reset(mContext, mListener);
1269         setUpSystemServiceForContext();
1270         when(mWifiNative.switchClientInterfaceToScanMode(any(), any()))
1271                 .thenReturn(true);
1272 
1273         mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE);
1274         mLooper.dispatchAll();
1275 
1276         verify(mImsMmTelManager).registerImsRegistrationCallback(
1277                 any(Executor.class),
1278                 any(RegistrationManager.RegistrationCallback.class));
1279         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
1280 
1281         mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE);
1282         mLooper.dispatchAll();
1283         // should not register another listener.
1284         verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any());
1285         verify(mImsMmTelManager, times(1)).registerImsRegistrationCallback(
1286                 any(Executor.class),
1287                 any(RegistrationManager.RegistrationCallback.class));
1288         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
1289         verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt());
1290 
1291         // Exceeding the timeout, wifi should be stopped.
1292         moveTimeForward(TEST_WIFI_OFF_DEFERRING_TIME_MS + 1000);
1293         mLooper.dispatchAll();
1294         verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE);
1295         verify(mImsMmTelManager).unregisterImsRegistrationCallback(
1296                 any(RegistrationManager.RegistrationCallback.class));
1297         assertNull(mImsMmTelManagerRegistrationCallback);
1298         verify(mWifiMetrics).noteWifiOff(eq(true), eq(true), anyInt());
1299     }
1300 
1301     /**
1302      * Stay at connected mode with IMS deferring time and Wifi calling
1303      * when the target state is not ROLE_CLIENT_SCAN_ONLY.
1304      *
1305      * Simulate a user toggle wifi multiple times before doing wifi stop and stay at
1306      * ON position.
1307      */
1308     @Test
1309     public void
stayAtConnectedModeWithWifiOffDeferringTimeAndWifiCallingTimedOutMultipleSwitch()1310             stayAtConnectedModeWithWifiOffDeferringTimeAndWifiCallingTimedOutMultipleSwitch()
1311             throws Exception {
1312         setUpVoWifiTest(true,
1313                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
1314 
1315         startClientInConnectModeAndVerifyEnabled();
1316         reset(mContext, mListener);
1317         setUpSystemServiceForContext();
1318         when(mWifiNative.switchClientInterfaceToScanMode(any(), any()))
1319                 .thenReturn(true);
1320 
1321         mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE);
1322         mLooper.dispatchAll();
1323         mClientModeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY, TEST_WORKSOURCE);
1324         mLooper.dispatchAll();
1325         mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE);
1326         mLooper.dispatchAll();
1327         mClientModeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY, TEST_WORKSOURCE);
1328         mLooper.dispatchAll();
1329 
1330         verify(mImsMmTelManager).registerImsRegistrationCallback(
1331                 any(Executor.class),
1332                 any(RegistrationManager.RegistrationCallback.class));
1333         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
1334 
1335         // should not register another listener.
1336         verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any());
1337         verify(mImsMmTelManager, times(1)).registerImsRegistrationCallback(
1338                 any(Executor.class),
1339                 any(RegistrationManager.RegistrationCallback.class));
1340         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
1341         verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt());
1342 
1343         // Exceeding the timeout, wifi should NOT be stopped.
1344         moveTimeForward(TEST_WIFI_OFF_DEFERRING_TIME_MS + 1000);
1345         mLooper.dispatchAll();
1346         verify(mWifiNative, never()).switchClientInterfaceToScanMode(
1347                 TEST_INTERFACE_NAME, TEST_WORKSOURCE);
1348         verify(mImsMmTelManager).unregisterImsRegistrationCallback(
1349                 any(RegistrationManager.RegistrationCallback.class));
1350         assertNull(mImsMmTelManagerRegistrationCallback);
1351         verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt());
1352     }
1353 
1354     /**
1355      * ClientMode stop properly with IMS deferring time without WifiCalling.
1356      */
1357     @Test
clientModeStopWithImsManagerException()1358     public void clientModeStopWithImsManagerException() throws Exception {
1359         setUpVoWifiTest(true,
1360                 TEST_WIFI_OFF_DEFERRING_TIME_MS);
1361         when(mImsMmTelManager.isAvailable(anyInt(), anyInt()))
1362                 .thenThrow(new RuntimeException("Test Runtime Exception"));
1363 
1364         startClientInConnectModeAndVerifyEnabled();
1365         reset(mContext, mListener);
1366         setUpSystemServiceForContext();
1367         mClientModeManager.stop();
1368         mLooper.dispatchAll();
1369         when(mClientModeImpl.hasQuit()).thenReturn(true);
1370         mClientModeManager.onClientModeImplQuit();
1371         verify(mListener).onStopped(mClientModeManager);
1372 
1373         verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED);
1374 
1375         verify(mImsMmTelManager, never()).registerImsRegistrationCallback(any(), any());
1376         verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any());
1377         verify(mWifiMetrics).noteWifiOff(eq(false), eq(false), anyInt());
1378 
1379         // on an explicit stop, we should not trigger the callback
1380         verifyNoMoreInteractions(mListener);
1381     }
1382 
1383     /**
1384      * ClientMode starts up in connect mode and then change connectivity roles.
1385      */
1386     @Test
clientInConnectModeChangeRoles()1387     public void clientInConnectModeChangeRoles() throws Exception {
1388         startClientInConnectModeAndVerifyEnabled();
1389         reset(mListener);
1390 
1391         // Set the same role again, no-op.
1392         assertEquals(ActiveModeManager.ROLE_CLIENT_PRIMARY, mClientModeManager.getRole());
1393         mClientModeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY, TEST_WORKSOURCE);
1394         mLooper.dispatchAll();
1395         verify(mWifiNative).replaceStaIfaceRequestorWs(
1396                 eq(TEST_INTERFACE_NAME), same(TEST_WORKSOURCE));
1397         verify(mListener, never()).onRoleChanged(any()); // no callback sent.
1398 
1399         // Change the connectivity role.
1400         ActiveModeManager.Listener<ConcreteClientModeManager> newListener =
1401                 mock(ActiveModeManager.Listener.class);
1402         mClientModeManager.setRole(
1403                 ActiveModeManager.ROLE_CLIENT_SECONDARY_TRANSIENT, TEST_WORKSOURCE, newListener);
1404         mLooper.dispatchAll();
1405         verify(mWifiNative, times(2)).replaceStaIfaceRequestorWs(
1406                 eq(TEST_INTERFACE_NAME), same(TEST_WORKSOURCE));
1407         verify(newListener).onRoleChanged(mClientModeManager); // callback sent on new listener.
1408         verifyNoMoreInteractions(mListener); // no callback sent on older listener.
1409     }
1410 
1411     @Test
clientInConnectModeChangeRolesNewWorkSource_WifiNativeFailed_noCallback()1412     public void clientInConnectModeChangeRolesNewWorkSource_WifiNativeFailed_noCallback()
1413             throws Exception {
1414         startClientInConnectModeAndVerifyEnabled();
1415         reset(mListener);
1416 
1417         when(mWifiNative.replaceStaIfaceRequestorWs(TEST_INTERFACE_NAME, TEST_WORKSOURCE2))
1418                 .thenReturn(false);
1419 
1420         // set new mode with new WorkSource
1421         mClientModeManager.setRole(ROLE_CLIENT_SECONDARY_TRANSIENT, TEST_WORKSOURCE2);
1422         mLooper.dispatchAll();
1423 
1424         verify(mWifiNative).replaceStaIfaceRequestorWs(
1425                 eq(TEST_INTERFACE_NAME), same(TEST_WORKSOURCE2));
1426         // no callback sent since replaceStaIfaceRequestorWs failed
1427         verify(mListener, never()).onRoleChanged(any());
1428     }
1429 
1430     @Test
setRoleBeforeInvokingListener()1431     public void setRoleBeforeInvokingListener() throws Exception {
1432         when(mWifiNative.setupInterfaceForClientInScanMode(any(), any()))
1433                 .thenReturn(TEST_INTERFACE_NAME);
1434         when(mWifiNative.switchClientInterfaceToConnectivityMode(any(), any()))
1435                 .thenReturn(true);
1436 
1437         doAnswer(new AnswerWithArguments() {
1438             public void answer(ActiveModeManager clientModeManager) throws Exception {
1439                 assertEquals(ROLE_CLIENT_SCAN_ONLY, clientModeManager.getRole());
1440             }
1441         }).when(mListener).onStarted(mClientModeManager);
1442         mClientModeManager = createClientModeManager(ROLE_CLIENT_SCAN_ONLY);
1443         mLooper.dispatchAll();
1444 
1445         ActiveModeManager.ClientRole lastRole = mClientModeManager.getRole();
1446         assertEquals(ROLE_CLIENT_SCAN_ONLY, lastRole);
1447         assertNull(mClientModeManager.getPreviousRole());
1448 
1449         verify(mWifiNative).setupInterfaceForClientInScanMode(
1450                 mInterfaceCallbackCaptor.capture(), eq(TEST_WORKSOURCE));
1451         mInterfaceCallbackCaptor.getValue().onUp(TEST_INTERFACE_NAME);
1452         mLooper.dispatchAll();
1453         verify(mListener).onStarted(mClientModeManager); // callback sent.
1454 
1455         // Change to connectivity role.
1456         long testChangeRoleTimestamp = 12234455L;
1457         when(mClock.getElapsedSinceBootMillis()).thenReturn(testChangeRoleTimestamp);
1458         doAnswer(new AnswerWithArguments() {
1459             public void answer(ActiveModeManager clientModeManager) throws Exception {
1460                 assertEquals(ActiveModeManager.ROLE_CLIENT_PRIMARY, clientModeManager.getRole());
1461             }
1462         }).when(mListener).onRoleChanged(mClientModeManager);
1463         mClientModeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY, TEST_WORKSOURCE);
1464         mLooper.dispatchAll();
1465         verify(mListener).onRoleChanged(mClientModeManager); // callback sent.
1466 
1467         // Verify the role is changed and previousRole is updated.
1468         assertEquals("Should equal previous role", lastRole,
1469                 mClientModeManager.getPreviousRole());
1470         assertEquals("The role change timestamp should match", testChangeRoleTimestamp,
1471                 mClientModeManager.getLastRoleChangeSinceBootMs());
1472     }
1473 
1474     @Test
propagateSettingsToClientModeImpl()1475     public void propagateSettingsToClientModeImpl() throws Exception {
1476         startClientInConnectModeAndVerifyEnabled();
1477         verify(mWifiInjector).makeClientModeImpl(any(), any(), eq(false));
1478         verify(mClientModeImpl).setShouldReduceNetworkScore(false);
1479 
1480         mClientModeManager.enableVerboseLogging(true);
1481         verify(mClientModeImpl).enableVerboseLogging(true);
1482 
1483         mClientModeManager.enableVerboseLogging(false);
1484         verify(mClientModeImpl).enableVerboseLogging(false);
1485 
1486         mClientModeManager.setShouldReduceNetworkScore(true);
1487         verify(mClientModeImpl).setShouldReduceNetworkScore(true);
1488 
1489         mClientModeManager.setShouldReduceNetworkScore(false);
1490         verify(mClientModeImpl, times(2)).setShouldReduceNetworkScore(false);
1491     }
1492 
1493     @Test
propagateConnectedWifiScorerToPrimaryClientModeImpl()1494     public void propagateConnectedWifiScorerToPrimaryClientModeImpl() throws Exception {
1495         startClientInConnectModeAndVerifyEnabled();
1496 
1497         IBinder iBinder = mock(IBinder.class);
1498         IWifiConnectedNetworkScorer iScorer = mock(IWifiConnectedNetworkScorer.class);
1499         mClientModeManager.setWifiConnectedNetworkScorer(iBinder, iScorer);
1500         verify(mClientModeImpl).setWifiConnectedNetworkScorer(iBinder, iScorer);
1501 
1502         mClientModeManager.clearWifiConnectedNetworkScorer();
1503         verify(mClientModeImpl).clearWifiConnectedNetworkScorer();
1504 
1505         mClientModeManager.setWifiConnectedNetworkScorer(iBinder, iScorer);
1506         verify(mClientModeImpl, times(2)).setWifiConnectedNetworkScorer(iBinder, iScorer);
1507     }
1508 
1509     @Test
updateConnectModeStateInAllRoles()1510     public void updateConnectModeStateInAllRoles() throws Exception {
1511         startClientInConnectModeAndVerifyEnabled();
1512         mClientModeManager.setRole(ROLE_CLIENT_SECONDARY_TRANSIENT, TEST_WORKSOURCE);
1513         mLooper.dispatchAll();
1514         mClientModeManager.stop();
1515         // disabling broadcast wasn't sent out (since role is secondary)
1516         verify(mContext, never()).sendStickyBroadcastAsUser(
1517                 argThat(intent ->
1518                         intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1)
1519                                 == WifiManager.WIFI_STATE_DISABLING),
1520                 any());
1521         // Wifi state should not be updated due to the role is not primary.
1522         verify(mActiveModeWarden, never()).setWifiStateForApiCalls(WIFI_STATE_DISABLING);
1523     }
1524 
1525     @Test
changeRoleResetsSettings()1526     public void changeRoleResetsSettings() throws Exception {
1527         startClientInConnectModeAndVerifyEnabled();
1528 
1529         verify(mClientModeImpl).setShouldReduceNetworkScore(false);
1530 
1531         mClientModeManager.setRole(ROLE_CLIENT_SECONDARY_TRANSIENT, TEST_WORKSOURCE);
1532         mLooper.dispatchAll();
1533 
1534         // reset upon role change
1535         verify(mClientModeImpl, times(2)).setShouldReduceNetworkScore(false);
1536     }
1537 
1538     @Test
sameRoleDoesntResetsSettings()1539     public void sameRoleDoesntResetsSettings() throws Exception {
1540         startClientInConnectModeAndVerifyEnabled();
1541 
1542         verify(mClientModeImpl).setShouldReduceNetworkScore(false);
1543 
1544         mClientModeManager.setRole(ROLE_CLIENT_PRIMARY, TEST_WORKSOURCE);
1545         mLooper.dispatchAll();
1546 
1547         // no role change, no reset
1548         verify(mClientModeImpl).setShouldReduceNetworkScore(false);
1549     }
1550 }
1551