| /* |
| * Copyright 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.server.wifi; |
| |
| import static android.net.wifi.WifiManager.EXTRA_PREVIOUS_WIFI_STATE; |
| import static android.net.wifi.WifiManager.EXTRA_WIFI_STATE; |
| import static android.net.wifi.WifiManager.WIFI_STATE_CHANGED_ACTION; |
| import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED; |
| import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING; |
| import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED; |
| import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING; |
| import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN; |
| |
| import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; |
| import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_PRIMARY; |
| import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SCAN_ONLY; |
| import static com.android.server.wifi.ActiveModeManager.ROLE_CLIENT_SECONDARY_TRANSIENT; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.mockito.Mockito.*; |
| import static org.mockito.Mockito.any; |
| import static org.mockito.Mockito.anyInt; |
| import static org.mockito.Mockito.doAnswer; |
| import static org.mockito.Mockito.lenient; |
| |
| import android.app.test.MockAnswerUtil.AnswerWithArguments; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.net.ConnectivityManager; |
| import android.net.ConnectivityManager.NetworkCallback; |
| import android.net.NetworkRequest; |
| import android.net.wifi.IWifiConnectedNetworkScorer; |
| import android.net.wifi.WifiManager; |
| import android.os.Handler; |
| import android.os.IBinder; |
| import android.os.PersistableBundle; |
| import android.os.UserHandle; |
| import android.os.WorkSource; |
| import android.os.test.TestLooper; |
| import android.telephony.AccessNetworkConstants; |
| import android.telephony.CarrierConfigManager; |
| import android.telephony.SubscriptionInfo; |
| import android.telephony.SubscriptionManager; |
| import android.telephony.ims.ImsMmTelManager; |
| import android.telephony.ims.RegistrationManager; |
| import android.test.suitebuilder.annotation.SmallTest; |
| import android.util.Log; |
| |
| import com.android.server.wifi.ClientModeManagerBroadcastQueue.QueuedBroadcast; |
| import com.android.wifi.resources.R; |
| |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.mockito.ArgumentCaptor; |
| import org.mockito.InOrder; |
| import org.mockito.Mock; |
| import org.mockito.MockitoAnnotations; |
| import org.mockito.MockitoSession; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.concurrent.Executor; |
| |
| /** |
| * Unit tests for {@link ConcreteClientModeManager}. |
| */ |
| @SmallTest |
| public class ConcreteClientModeManagerTest extends WifiBaseTest { |
| private static final String TAG = "ClientModeManagerTest"; |
| private static final String TEST_INTERFACE_NAME = "testif0"; |
| private static final String OTHER_INTERFACE_NAME = "notTestIf"; |
| private static final int TEST_WIFI_OFF_DEFERRING_TIME_MS = 4000; |
| private static final int TEST_ACTIVE_SUBSCRIPTION_ID = 1; |
| private static final WorkSource TEST_WORKSOURCE = new WorkSource(); |
| private static final WorkSource TEST_WORKSOURCE2 = new WorkSource(); |
| |
| TestLooper mLooper; |
| |
| ConcreteClientModeManager mClientModeManager; |
| |
| @Mock Context mContext; |
| @Mock WifiMetrics mWifiMetrics; |
| @Mock WifiNative mWifiNative; |
| @Mock Clock mClock; |
| @Mock ActiveModeManager.Listener<ConcreteClientModeManager> mListener; |
| @Mock WakeupController mWakeupController; |
| @Mock WifiInjector mWifiInjector; |
| @Mock ClientModeImpl mClientModeImpl; |
| @Mock CarrierConfigManager mCarrierConfigManager; |
| @Mock PersistableBundle mCarrierConfigBundle; |
| @Mock ImsMmTelManager mImsMmTelManager; |
| @Mock ConnectivityManager mConnectivityManager; |
| @Mock SubscriptionManager mSubscriptionManager; |
| @Mock SubscriptionInfo mActiveSubscriptionInfo; |
| @Mock SelfRecovery mSelfRecovery; |
| @Mock WifiGlobals mWifiGlobals; |
| @Mock ScanOnlyModeImpl mScanOnlyModeImpl; |
| @Mock DefaultClientModeManager mDefaultClientModeManager; |
| @Mock ClientModeManagerBroadcastQueue mBroadcastQueue; |
| |
| private RegistrationManager.RegistrationCallback mImsMmTelManagerRegistrationCallback = null; |
| private @RegistrationManager.ImsRegistrationState int mCurrentImsRegistrationState = |
| RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED; |
| private @AccessNetworkConstants.TransportType int mCurrentImsConnectionType = |
| AccessNetworkConstants.TRANSPORT_TYPE_INVALID; |
| private NetworkRequest mImsRequest = null; |
| private NetworkCallback mImsNetworkCallback = null; |
| private Handler mImsNetworkCallbackHandler = null; |
| private long mElapsedSinceBootMillis = 0L; |
| private List<SubscriptionInfo> mSubscriptionInfoList = new ArrayList<>(); |
| private MockResources mResources; |
| |
| private MockitoSession mStaticMockSession = null; |
| |
| final ArgumentCaptor<WifiNative.InterfaceCallback> mInterfaceCallbackCaptor = |
| ArgumentCaptor.forClass(WifiNative.InterfaceCallback.class); |
| |
| /** |
| * If mContext is reset, call it again to ensure system services could be retrieved |
| * from the context. |
| */ |
| private void setUpSystemServiceForContext() { |
| when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)) |
| .thenReturn(mCarrierConfigManager); |
| when(mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)) |
| .thenReturn(mSubscriptionManager); |
| when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)) |
| .thenReturn(mConnectivityManager); |
| when(mContext.getResources()).thenReturn(mResources); |
| when(mWifiInjector.makeClientModeImpl(any(), any(), anyBoolean())) |
| .thenReturn(mClientModeImpl); |
| when(mWifiInjector.makeScanOnlyModeImpl(any())).thenReturn(mScanOnlyModeImpl); |
| } |
| |
| /* |
| * Use this helper to move mock looper and clock together. |
| */ |
| private void moveTimeForward(long timeMillis) { |
| mLooper.moveTimeForward(timeMillis); |
| mElapsedSinceBootMillis += timeMillis; |
| } |
| |
| |
| @Before |
| public void setUp() throws Exception { |
| MockitoAnnotations.initMocks(this); |
| |
| // Prepare data |
| mResources = new MockResources(); |
| mResources.setInteger(R.integer.config_wifiDelayDisconnectOnImsLostMs, 0); |
| mSubscriptionInfoList.add(mActiveSubscriptionInfo); |
| |
| setUpSystemServiceForContext(); |
| |
| /** |
| * default mock for IMS deregistration: |
| * * No wifi calling |
| * * No network |
| * * no deferring time for wifi off |
| */ |
| mStaticMockSession = mockitoSession() |
| .mockStatic(ImsMmTelManager.class) |
| .mockStatic(SubscriptionManager.class) |
| .startMocking(); |
| lenient().when(ImsMmTelManager.createForSubscriptionId(eq(TEST_ACTIVE_SUBSCRIPTION_ID))) |
| .thenReturn(mImsMmTelManager); |
| lenient().when(SubscriptionManager.isValidSubscriptionId(eq(TEST_ACTIVE_SUBSCRIPTION_ID))) |
| .thenReturn(true); |
| doAnswer(new AnswerWithArguments() { |
| public void answer(Executor executor, RegistrationManager.RegistrationCallback c) { |
| mImsMmTelManagerRegistrationCallback = c; |
| // When the callback is registered, it will initiate the callback c to |
| // be called with the current registration state. |
| switch (mCurrentImsRegistrationState) { |
| case RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED: |
| c.onUnregistered(null); |
| break; |
| case RegistrationManager.REGISTRATION_STATE_REGISTERED: |
| c.onRegistered(mCurrentImsConnectionType); |
| break; |
| } |
| } |
| }).when(mImsMmTelManager).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| doAnswer(new AnswerWithArguments() { |
| public void answer(RegistrationManager.RegistrationCallback c) { |
| if (mImsMmTelManagerRegistrationCallback == c) { |
| mImsMmTelManagerRegistrationCallback = null; |
| } |
| } |
| }).when(mImsMmTelManager).unregisterImsRegistrationCallback( |
| any(RegistrationManager.RegistrationCallback.class)); |
| when(mImsMmTelManager.isAvailable(anyInt(), anyInt())).thenReturn(false); |
| |
| when(mActiveSubscriptionInfo.getSubscriptionId()).thenReturn(TEST_ACTIVE_SUBSCRIPTION_ID); |
| when(mSubscriptionManager.getActiveSubscriptionInfoList()) |
| .thenReturn(mSubscriptionInfoList); |
| when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfigBundle); |
| when(mCarrierConfigBundle |
| .getInt(eq(CarrierConfigManager.Ims.KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT))) |
| .thenReturn(0); |
| doAnswer(new AnswerWithArguments() { |
| public void answer(NetworkRequest req, NetworkCallback callback, Handler handler) { |
| mImsRequest = req; |
| mImsNetworkCallback = callback; |
| mImsNetworkCallbackHandler = handler; |
| } |
| }).when(mConnectivityManager).registerNetworkCallback(any(), any(), any()); |
| doAnswer(new AnswerWithArguments() { |
| public void answer(NetworkCallback callback) { |
| if (mImsNetworkCallback == callback) mImsNetworkCallback = null; |
| } |
| }).when(mConnectivityManager).unregisterNetworkCallback(any(NetworkCallback.class)); |
| doAnswer(new AnswerWithArguments() { |
| public long answer() { |
| return mElapsedSinceBootMillis; |
| } |
| }).when(mClock).getElapsedSinceBootMillis(); |
| when(mWifiNative.replaceStaIfaceRequestorWs(TEST_INTERFACE_NAME, TEST_WORKSOURCE)) |
| .thenReturn(true); |
| doAnswer(new AnswerWithArguments() { |
| public void answer(ClientModeManager manager, QueuedBroadcast broadcast) { |
| broadcast.send(); |
| } |
| }).when(mBroadcastQueue).queueOrSendBroadcast(any(), any()); |
| |
| mLooper = new TestLooper(); |
| } |
| |
| @After |
| public void cleanUp() throws Exception { |
| mStaticMockSession.finishMocking(); |
| } |
| |
| private ConcreteClientModeManager createClientModeManager(ActiveModeManager.ClientRole role) { |
| return new ConcreteClientModeManager(mContext, mLooper.getLooper(), mClock, mWifiNative, |
| mListener, mWifiMetrics, mWakeupController, mWifiInjector, mSelfRecovery, |
| mWifiGlobals, mDefaultClientModeManager, 0, TEST_WORKSOURCE, role, |
| mBroadcastQueue, false); |
| } |
| |
| private void startClientInScanOnlyModeAndVerifyEnabled() throws Exception { |
| when(mWifiNative.setupInterfaceForClientInScanMode(any(), any())) |
| .thenReturn(TEST_INTERFACE_NAME); |
| mClientModeManager = createClientModeManager(ROLE_CLIENT_SCAN_ONLY); |
| mLooper.dispatchAll(); |
| |
| verify(mWifiNative).setupInterfaceForClientInScanMode( |
| mInterfaceCallbackCaptor.capture(), eq(TEST_WORKSOURCE)); |
| verify(mWifiInjector, never()).makeClientModeImpl(any(), any(), anyBoolean()); |
| |
| // now mark the interface as up |
| mInterfaceCallbackCaptor.getValue().onUp(TEST_INTERFACE_NAME); |
| mLooper.dispatchAll(); |
| |
| // Ensure that no public broadcasts were sent. |
| verifyNoMoreInteractions(mContext); |
| verify(mListener).onStarted(mClientModeManager); |
| verify(mWifiNative).setScanMode(TEST_INTERFACE_NAME, true); |
| } |
| |
| private void startClientInConnectModeAndVerifyEnabled() throws Exception { |
| when(mWifiNative.setupInterfaceForClientInScanMode(any(), any())) |
| .thenReturn(TEST_INTERFACE_NAME); |
| when(mWifiNative.switchClientInterfaceToConnectivityMode(any(), any())) |
| .thenReturn(true); |
| mClientModeManager = createClientModeManager(ROLE_CLIENT_PRIMARY); |
| mLooper.dispatchAll(); |
| |
| verify(mWifiNative).setupInterfaceForClientInScanMode( |
| mInterfaceCallbackCaptor.capture(), eq(TEST_WORKSOURCE)); |
| verify(mWifiNative).switchClientInterfaceToConnectivityMode( |
| TEST_INTERFACE_NAME, TEST_WORKSOURCE); |
| verify(mWifiInjector) |
| .makeClientModeImpl(eq(TEST_INTERFACE_NAME), eq(mClientModeManager), anyBoolean()); |
| |
| // now mark the interface as up |
| mInterfaceCallbackCaptor.getValue().onUp(TEST_INTERFACE_NAME); |
| mLooper.dispatchAll(); |
| |
| ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); |
| verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(), |
| eq(UserHandle.ALL)); |
| |
| List<Intent> intents = intentCaptor.getAllValues(); |
| assertEquals(2, intents.size()); |
| Log.d(TAG, "captured intents: " + intents); |
| checkWifiConnectModeStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING, |
| WIFI_STATE_DISABLED); |
| checkWifiConnectModeStateChangedBroadcast(intents.get(1), WIFI_STATE_ENABLED, |
| WIFI_STATE_ENABLING); |
| assertEquals(WIFI_STATE_ENABLED, mClientModeManager.syncGetWifiState()); |
| |
| verify(mListener).onStarted(mClientModeManager); |
| } |
| |
| private void checkWifiConnectModeStateChangedBroadcast( |
| Intent intent, int expectedCurrentState, int expectedPrevState) { |
| String action = intent.getAction(); |
| assertEquals(WIFI_STATE_CHANGED_ACTION, action); |
| int currentState = intent.getIntExtra(EXTRA_WIFI_STATE, WIFI_STATE_UNKNOWN); |
| assertEquals(expectedCurrentState, currentState); |
| int prevState = intent.getIntExtra(EXTRA_PREVIOUS_WIFI_STATE, WIFI_STATE_UNKNOWN); |
| assertEquals(expectedPrevState, prevState); |
| } |
| |
| private void verifyConnectModeNotificationsForCleanShutdown(int fromState) { |
| ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); |
| verify(mContext, atLeastOnce()) |
| .sendStickyBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL)); |
| |
| List<Intent> intents = intentCaptor.getAllValues(); |
| assertTrue(intents.size() >= 2); |
| checkWifiConnectModeStateChangedBroadcast(intents.get(intents.size() - 2), |
| WIFI_STATE_DISABLING, fromState); |
| checkWifiConnectModeStateChangedBroadcast(intents.get(intents.size() - 1), |
| WIFI_STATE_DISABLED, WIFI_STATE_DISABLING); |
| assertEquals(WIFI_STATE_DISABLED, mClientModeManager.syncGetWifiState()); |
| } |
| |
| private void verifyConnectModeNotificationsForFailure() { |
| ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); |
| verify(mContext, atLeastOnce()) |
| .sendStickyBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL)); |
| |
| List<Intent> intents = intentCaptor.getAllValues(); |
| assertEquals(2, intents.size()); |
| checkWifiConnectModeStateChangedBroadcast(intents.get(0), WIFI_STATE_DISABLING, |
| WIFI_STATE_UNKNOWN); |
| checkWifiConnectModeStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED, |
| WIFI_STATE_DISABLING); |
| assertEquals(WIFI_STATE_DISABLED, mClientModeManager.syncGetWifiState()); |
| } |
| |
| /** |
| * ClientMode start sets up an interface in ClientMode. |
| */ |
| @Test |
| public void clientInConnectModeStartCreatesClientInterface() throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| } |
| |
| /** |
| * ClientMode start sets up an interface in ClientMode. |
| */ |
| @Test |
| public void clientInScanOnlyModeStartCreatesClientInterface() throws Exception { |
| startClientInScanOnlyModeAndVerifyEnabled(); |
| |
| mClientModeManager.getFactoryMacAddress(); |
| // in scan only mode, should get value from ScanOnlyModeImpl |
| verify(mScanOnlyModeImpl).getFactoryMacAddress(); |
| } |
| |
| /** |
| * Switch ClientModeManager from ScanOnly mode To Connect mode. |
| */ |
| @Test |
| public void switchFromScanOnlyModeToConnectMode() throws Exception { |
| startClientInScanOnlyModeAndVerifyEnabled(); |
| |
| when(mWifiNative.switchClientInterfaceToConnectivityMode(any(), any())) |
| .thenReturn(true); |
| mClientModeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| |
| verify(mWifiNative).setScanMode(TEST_INTERFACE_NAME, false); |
| |
| verify(mWifiInjector) |
| .makeClientModeImpl(eq(TEST_INTERFACE_NAME), eq(mClientModeManager), anyBoolean()); |
| |
| ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); |
| verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(), |
| eq(UserHandle.ALL)); |
| |
| List<Intent> intents = intentCaptor.getAllValues(); |
| assertEquals(2, intents.size()); |
| Log.d(TAG, "captured intents: " + intents); |
| checkWifiConnectModeStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING, |
| WIFI_STATE_DISABLED); |
| checkWifiConnectModeStateChangedBroadcast(intents.get(1), WIFI_STATE_ENABLED, |
| WIFI_STATE_ENABLING); |
| assertEquals(WIFI_STATE_ENABLED, mClientModeManager.syncGetWifiState()); |
| |
| verify(mListener).onStarted(mClientModeManager); |
| verify(mListener).onRoleChanged(mClientModeManager); |
| |
| mClientModeManager.getFactoryMacAddress(); |
| // in client mode, should get value from ClientModeImpl |
| verify(mClientModeImpl).getFactoryMacAddress(); |
| } |
| |
| /** |
| * Verify that no more public broadcasts are sent out after |
| * setWifiStateChangeBroadcastEnabled(false) is called. |
| */ |
| @Test |
| public void testDisableWifiStateChangedBroadcasts() throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| |
| mClientModeManager.setWifiStateChangeBroadcastEnabled(false); |
| mClientModeManager.stop(); |
| mLooper.dispatchAll(); |
| |
| verify(mClientModeImpl).stop(); |
| assertEquals(WIFI_STATE_DISABLED, mClientModeManager.syncGetWifiState()); |
| |
| // Ensure that only public broadcasts for the "start" events were sent. |
| ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); |
| verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(), |
| eq(UserHandle.ALL)); |
| |
| List<Intent> intents = intentCaptor.getAllValues(); |
| assertEquals(2, intents.size()); |
| Log.d(TAG, "captured intents: " + intents); |
| checkWifiConnectModeStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING, |
| WIFI_STATE_DISABLED); |
| checkWifiConnectModeStateChangedBroadcast(intents.get(1), WIFI_STATE_ENABLED, |
| WIFI_STATE_ENABLING); |
| } |
| |
| /** |
| * Switch ClientModeManager from Connect mode to ScanOnly mode. |
| */ |
| @Test |
| public void switchFromConnectModeToScanOnlyMode() throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| |
| when(mWifiNative.switchClientInterfaceToScanMode(any(), any())) |
| .thenReturn(true); |
| mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| |
| verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED); |
| verify(mWifiNative).setupInterfaceForClientInScanMode( |
| mInterfaceCallbackCaptor.capture(), eq(TEST_WORKSOURCE)); |
| verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE); |
| verify(mClientModeImpl).stop(); |
| |
| verify(mContext).getSystemService(anyString()); |
| verify(mImsMmTelManager, never()).registerImsRegistrationCallback(any(), any()); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| |
| // Ensure that no public broadcasts were sent. |
| verifyNoMoreInteractions(mContext); |
| verify(mListener).onStarted(mClientModeManager); |
| verify(mListener).onRoleChanged(mClientModeManager); |
| } |
| |
| /** |
| * ClientMode increments failure metrics when failing to setup client mode in connectivity mode. |
| */ |
| @Test |
| public void detectAndReportErrorWhenSetupForClientInConnectivityModeWifiNativeFailure() |
| throws Exception { |
| when(mWifiNative.setupInterfaceForClientInScanMode(any(), any())) |
| .thenReturn(TEST_INTERFACE_NAME); |
| when(mWifiNative.switchClientInterfaceToConnectivityMode(any(), any())).thenReturn(false); |
| |
| mClientModeManager = createClientModeManager(ROLE_CLIENT_PRIMARY); |
| mLooper.dispatchAll(); |
| |
| ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); |
| verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(), |
| eq(UserHandle.ALL)); |
| List<Intent> intents = intentCaptor.getAllValues(); |
| assertEquals(2, intents.size()); |
| checkWifiConnectModeStateChangedBroadcast(intents.get(0), WIFI_STATE_ENABLING, |
| WIFI_STATE_DISABLED); |
| checkWifiConnectModeStateChangedBroadcast(intents.get(1), WIFI_STATE_DISABLED, |
| WIFI_STATE_UNKNOWN); |
| assertEquals(WIFI_STATE_DISABLED, mClientModeManager.syncGetWifiState()); |
| verify(mListener).onStartFailure(mClientModeManager); |
| } |
| |
| /** Tests failure when setting up iface for scan only mode. */ |
| @Test |
| public void detectAndReportErrorWhenSetupInterfaceForClientInScanModeWifiNativeFailure() |
| throws Exception { |
| // failed to setup iface in Scan Only mode |
| when(mWifiNative.setupInterfaceForClientInScanMode(any(), any())).thenReturn(null); |
| |
| mClientModeManager = createClientModeManager(ROLE_CLIENT_PRIMARY); |
| mLooper.dispatchAll(); |
| |
| assertEquals(WIFI_STATE_DISABLED, mClientModeManager.syncGetWifiState()); |
| verify(mListener).onStartFailure(mClientModeManager); |
| |
| mClientModeManager.getFactoryMacAddress(); |
| // wifi is off, should get value from DefaultClientModeManager |
| verify(mDefaultClientModeManager).getFactoryMacAddress(); |
| } |
| |
| /** |
| * ClientMode stop before start has been processed properly cleans up state & invokes the |
| * onStopped callback. |
| */ |
| @Test |
| public void clientModeStopBeforeStartCleansUpState() throws Exception { |
| mClientModeManager = createClientModeManager(ROLE_CLIENT_PRIMARY); |
| // Invoke stop before the internal start is processed by the state machine. |
| mClientModeManager.stop(); |
| mLooper.dispatchAll(); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener).onStopped(mClientModeManager); |
| |
| // Don't initiate wifi native setup. |
| verifyNoMoreInteractions(mListener, mWifiNative); |
| assertNull(mClientModeManager.getRole()); |
| assertNull(mClientModeManager.getPreviousRole()); |
| } |
| |
| /** |
| * ClientMode stop properly cleans up state & invokes the onStopped callback. |
| */ |
| @Test |
| public void clientModeStopCleansUpState() throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| mClientModeManager.stop(); |
| mLooper.dispatchAll(); |
| // role has not been reset yet |
| ActiveModeManager.ClientRole lastRole = mClientModeManager.getRole(); |
| assertNotNull(lastRole); |
| assertNull(mClientModeManager.getPreviousRole()); |
| |
| long testChangeRoleTimestamp = 12234455L; |
| when(mClock.getElapsedSinceBootMillis()).thenReturn(testChangeRoleTimestamp); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener).onStopped(mClientModeManager); |
| |
| // then role will be reset |
| assertNull(mClientModeManager.getRole()); |
| assertEquals("Should equal previous role", lastRole, |
| mClientModeManager.getPreviousRole()); |
| assertEquals("The role change timestamp should match", testChangeRoleTimestamp, |
| mClientModeManager.getLastRoleChangeSinceBootMs()); |
| |
| verify(mImsMmTelManager, never()).registerImsRegistrationCallback(any(), any()); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| |
| verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED); |
| |
| // on an explicit stop, we should not trigger the callback |
| verifyNoMoreInteractions(mListener); |
| } |
| |
| /** |
| * Triggering interface down when ClientMode is active properly exits the active state. |
| */ |
| @Test |
| public void clientModeStartedStopsWhenInterfaceDown() throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext); |
| setUpSystemServiceForContext(); |
| when(mWifiGlobals.isConnectedMacRandomizationEnabled()).thenReturn(false); |
| mInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME); |
| mLooper.dispatchAll(); |
| verify(mSelfRecovery).trigger(SelfRecovery.REASON_STA_IFACE_DOWN); |
| verifyConnectModeNotificationsForFailure(); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener).onStopped(mClientModeManager); |
| } |
| |
| /** |
| * Triggering interface down when ClientMode is active and Connected MacRandomization is enabled |
| * does not exit the active state. |
| */ |
| @Test |
| public void clientModeStartedWithConnectedMacRandDoesNotStopWhenInterfaceDown() |
| throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext); |
| setUpSystemServiceForContext(); |
| when(mWifiGlobals.isConnectedMacRandomizationEnabled()).thenReturn(true); |
| when(mClientModeImpl.isConnecting()).thenReturn(true); |
| mInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME); |
| mLooper.dispatchAll(); |
| verify(mSelfRecovery, never()).trigger(SelfRecovery.REASON_STA_IFACE_DOWN); |
| verify(mContext, never()).sendStickyBroadcastAsUser(any(), any()); |
| } |
| |
| /** |
| * Testing the handling of an interface destroyed notification. |
| */ |
| @Test |
| public void clientModeStartedStopsOnInterfaceDestroyed() throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext); |
| setUpSystemServiceForContext(); |
| mInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME); |
| mLooper.dispatchAll(); |
| verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED); |
| verify(mClientModeImpl).handleIfaceDestroyed(); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener).onStopped(mClientModeManager); |
| } |
| |
| /** |
| * Verify that onDestroyed after client mode is stopped doesn't trigger a callback. |
| */ |
| @Test |
| public void noCallbackOnInterfaceDestroyedWhenAlreadyStopped() throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| |
| reset(mListener); |
| |
| mClientModeManager.stop(); |
| mLooper.dispatchAll(); |
| |
| // now trigger interface destroyed and make sure callback doesn't get called |
| mInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME); |
| mLooper.dispatchAll(); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener).onStopped(mClientModeManager); |
| |
| verifyNoMoreInteractions(mListener); |
| verify(mClientModeImpl, never()).handleIfaceDestroyed(); |
| } |
| |
| /** |
| * Entering ScanOnly state starts the WakeupController. |
| */ |
| @Test |
| public void scanModeEnterStartsWakeupController() throws Exception { |
| startClientInScanOnlyModeAndVerifyEnabled(); |
| |
| verify(mWakeupController).start(); |
| } |
| |
| /** |
| * Exiting ScanOnly state stops the WakeupController. |
| */ |
| @Test |
| public void scanModeExitStopsWakeupController() throws Exception { |
| startClientInScanOnlyModeAndVerifyEnabled(); |
| |
| mClientModeManager.stop(); |
| mLooper.dispatchAll(); |
| |
| assertNull(mClientModeManager.getRole()); |
| |
| InOrder inOrder = inOrder(mWakeupController, mWifiNative, mListener); |
| |
| inOrder.verify(mListener).onStarted(mClientModeManager); |
| inOrder.verify(mWakeupController).start(); |
| inOrder.verify(mWakeupController).stop(); |
| inOrder.verify(mWifiNative).teardownInterface(eq(TEST_INTERFACE_NAME)); |
| } |
| |
| private void setUpVoWifiTest( |
| boolean isWifiCallingAvailable, |
| int wifiOffDeferringTimeMs) { |
| mCurrentImsRegistrationState = (isWifiCallingAvailable) |
| ? RegistrationManager.REGISTRATION_STATE_REGISTERED |
| : RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED; |
| mCurrentImsConnectionType = (isWifiCallingAvailable) |
| ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN |
| : AccessNetworkConstants.TRANSPORT_TYPE_WWAN; |
| when(mImsMmTelManager.isAvailable(anyInt(), anyInt())).thenReturn(isWifiCallingAvailable); |
| when(mCarrierConfigBundle |
| .getInt(eq(CarrierConfigManager.Ims.KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT))) |
| .thenReturn(wifiOffDeferringTimeMs); |
| } |
| |
| /** |
| * ClientMode stop properly with IMS deferring time without WifiCalling. |
| */ |
| @Test |
| public void clientModeStopWithWifiOffDeferringTimeNoWifiCalling() throws Exception { |
| setUpVoWifiTest(false, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| mClientModeManager.stop(); |
| mLooper.dispatchAll(); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener).onStopped(mClientModeManager); |
| |
| verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED); |
| |
| verify(mImsMmTelManager, never()).registerImsRegistrationCallback(any(), any()); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mWifiMetrics).noteWifiOff(eq(false), eq(false), anyInt()); |
| |
| // on an explicit stop, we should not trigger the callback |
| verifyNoMoreInteractions(mListener); |
| } |
| |
| /** |
| * ClientMode stop properly with IMS deferring time and IMS is registered on WWAN. |
| */ |
| @Test |
| public void clientModeStopWithWifiOffDeferringTimeAndImsOnWwan() throws Exception { |
| setUpVoWifiTest(true, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| mCurrentImsConnectionType = AccessNetworkConstants.TRANSPORT_TYPE_WWAN; |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| mClientModeManager.stop(); |
| mLooper.dispatchAll(); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener).onStopped(mClientModeManager); |
| |
| verify(mImsMmTelManager).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager).unregisterImsRegistrationCallback( |
| any(RegistrationManager.RegistrationCallback.class)); |
| assertNull(mImsMmTelManagerRegistrationCallback); |
| verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt()); |
| |
| verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED); |
| |
| // on an explicit stop, we should not trigger the callback |
| verifyNoMoreInteractions(mListener); |
| } |
| |
| /** |
| * ClientMode stop properly with IMS deferring time, Wifi calling. |
| */ |
| @Test |
| public void clientModeStopWithWifiOffDeferringTimeWithWifiCalling() throws Exception { |
| setUpVoWifiTest(true, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| mClientModeManager.stop(); |
| mLooper.dispatchAll(); |
| |
| // Not yet finish IMS deregistration. |
| verify(mImsMmTelManager).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mListener, never()).onStopped(any()); |
| verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt()); |
| |
| // Notify wifi service IMS service is de-registered. |
| assertNotNull(mImsMmTelManagerRegistrationCallback); |
| mImsMmTelManagerRegistrationCallback.onUnregistered(null); |
| assertNotNull(mImsNetworkCallback); |
| mImsNetworkCallback.onLost(null); |
| mLooper.dispatchAll(); |
| |
| // Now Wifi could be turned off actually. |
| verify(mImsMmTelManager).unregisterImsRegistrationCallback( |
| any(RegistrationManager.RegistrationCallback.class)); |
| assertNull(mImsMmTelManagerRegistrationCallback); |
| assertNull(mImsNetworkCallback); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener).onStopped(mClientModeManager); |
| verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt()); |
| |
| verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED); |
| |
| // on an explicit stop, we should not trigger the callback |
| verifyNoMoreInteractions(mListener); |
| } |
| |
| /** |
| * ClientMode stop properly with IMS deferring time, Wifi calling. |
| * |
| * The network losts first and then IMS is de-registered. |
| * The WIFI should be off after IMS deregistration. |
| */ |
| @Test |
| public void clientModeStopWithWifiOffDeferringTimeWithWifiCallingAndNetworkLostFirst() |
| throws Exception { |
| setUpVoWifiTest(true, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| mClientModeManager.stop(); |
| mLooper.dispatchAll(); |
| |
| // Not yet finish IMS deregistration. |
| verify(mImsMmTelManager).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener, never()).onStopped(any()); |
| verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt()); |
| |
| // Notify wifi service the network lost. |
| assertNotNull(mImsNetworkCallback); |
| mImsNetworkCallback.onLost(null); |
| mLooper.dispatchAll(); |
| |
| // Since IMS service is not de-registered yet, wifi should be available. |
| moveTimeForward(1000); |
| mLooper.dispatchAll(); |
| verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any()); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt()); |
| |
| // Notify wifi service IMS service is de-registered. |
| assertNotNull(mImsMmTelManagerRegistrationCallback); |
| mImsMmTelManagerRegistrationCallback.onUnregistered(null); |
| mLooper.dispatchAll(); |
| |
| // Now Wifi could be turned off actually. |
| verify(mImsMmTelManager).unregisterImsRegistrationCallback( |
| any(RegistrationManager.RegistrationCallback.class)); |
| assertNull(mImsMmTelManagerRegistrationCallback); |
| assertNull(mImsNetworkCallback); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener).onStopped(mClientModeManager); |
| verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt()); |
| |
| verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED); |
| |
| // on an explicit stop, we should not trigger the callback |
| verifyNoMoreInteractions(mListener); |
| } |
| |
| /** |
| * ClientMode stop properly with IMS deferring time and Wifi calling. |
| * |
| * IMS deregistration is done before reaching the timeout. |
| */ |
| @Test |
| public void clientModeStopWithWifiOffDeferringTimeAndWifiCallingOnImsRegistered() |
| throws Exception { |
| setUpVoWifiTest(true, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| mClientModeManager.stop(); |
| mLooper.dispatchAll(); |
| |
| // Not yet finish IMS deregistration. |
| verify(mImsMmTelManager).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener, never()).onStopped(any()); |
| verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt()); |
| |
| // Notify wifi service IMS service is de-registered. |
| assertNotNull(mImsMmTelManagerRegistrationCallback); |
| mImsMmTelManagerRegistrationCallback.onRegistered(0); |
| mLooper.dispatchAll(); |
| |
| // Now Wifi could be turned off actually. |
| verify(mImsMmTelManager).unregisterImsRegistrationCallback( |
| any(RegistrationManager.RegistrationCallback.class)); |
| assertNull(mImsMmTelManagerRegistrationCallback); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener).onStopped(mClientModeManager); |
| verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt()); |
| |
| verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED); |
| |
| // on an explicit stop, we should not trigger the callback |
| verifyNoMoreInteractions(mListener); |
| } |
| |
| /** |
| * ClientMode stop properly with IMS deferring time and Wifi calling. |
| * |
| * IMS deregistration is NOT done before reaching the timeout. |
| */ |
| @Test |
| public void clientModeStopWithWifiOffDeferringTimeAndWifiCallingTimedOut() |
| throws Exception { |
| setUpVoWifiTest(true, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| mClientModeManager.stop(); |
| mLooper.dispatchAll(); |
| verify(mImsMmTelManager).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener, never()).onStopped(any()); |
| |
| // 1/2 deferring time passed, should be still waiting for the callback. |
| moveTimeForward(TEST_WIFI_OFF_DEFERRING_TIME_MS / 2); |
| mLooper.dispatchAll(); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mListener, never()).onStopped(any()); |
| verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt()); |
| |
| // Exceeding the timeout, wifi should be stopped. |
| moveTimeForward(TEST_WIFI_OFF_DEFERRING_TIME_MS / 2 + 1000); |
| mLooper.dispatchAll(); |
| verify(mImsMmTelManager).unregisterImsRegistrationCallback( |
| any(RegistrationManager.RegistrationCallback.class)); |
| assertNull(mImsMmTelManagerRegistrationCallback); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener).onStopped(mClientModeManager); |
| verify(mWifiMetrics).noteWifiOff(eq(true), eq(true), anyInt()); |
| |
| verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED); |
| |
| // on an explicit stop, we should not trigger the callback |
| verifyNoMoreInteractions(mListener); |
| } |
| |
| /** |
| * ClientMode stop properly with IMS deferring time and Wifi calling. |
| * |
| * IMS deregistration is NOT done before reaching the timeout with multiple stop calls. |
| */ |
| @Test |
| public void clientModeStopWithWifiOffDeferringTimeAndWifiCallingTimedOutMultipleStop() |
| throws Exception { |
| setUpVoWifiTest(true, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| mClientModeManager.stop(); |
| mLooper.dispatchAll(); |
| verify(mImsMmTelManager).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mListener, never()).onStopped(any()); |
| |
| mClientModeManager.stop(); |
| mLooper.dispatchAll(); |
| // should not register another listener. |
| verify(mImsMmTelManager, times(1)).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mListener, never()).onStopped(any()); |
| verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt()); |
| |
| // Exceeding the timeout, wifi should be stopped. |
| moveTimeForward(TEST_WIFI_OFF_DEFERRING_TIME_MS + 1000); |
| mLooper.dispatchAll(); |
| verify(mImsMmTelManager).unregisterImsRegistrationCallback( |
| any(RegistrationManager.RegistrationCallback.class)); |
| assertNull(mImsMmTelManagerRegistrationCallback); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener).onStopped(mClientModeManager); |
| verify(mWifiMetrics).noteWifiOff(eq(true), eq(true), anyInt()); |
| |
| verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED); |
| |
| // on an explicit stop, we should not trigger the callback |
| verifyNoMoreInteractions(mListener); |
| } |
| |
| /** |
| * Switch to scan mode properly with IMS deferring time without WifiCalling. |
| */ |
| @Test |
| public void switchToScanOnlyModeWithWifiOffDeferringTimeNoWifiCalling() throws Exception { |
| setUpVoWifiTest(false, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| when(mWifiNative.switchClientInterfaceToScanMode(any(), any())) |
| .thenReturn(true); |
| |
| mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| |
| verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE); |
| verify(mImsMmTelManager, never()).registerImsRegistrationCallback(any(), any()); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mWifiMetrics).noteWifiOff(eq(false), eq(false), anyInt()); |
| } |
| |
| /** |
| * Switch to scan mode properly with IMS deferring time and IMS is registered on WWAN. |
| */ |
| @Test |
| public void switchToScanOnlyModeWithWifiOffDeferringTimeAndImsOnWwan() throws Exception { |
| setUpVoWifiTest(true, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| mCurrentImsConnectionType = AccessNetworkConstants.TRANSPORT_TYPE_WWAN; |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| when(mWifiNative.switchClientInterfaceToScanMode(any(), any())) |
| .thenReturn(true); |
| |
| mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| |
| verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE); |
| |
| verify(mImsMmTelManager).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager).unregisterImsRegistrationCallback( |
| any(RegistrationManager.RegistrationCallback.class)); |
| assertNull(mImsMmTelManagerRegistrationCallback); |
| verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt()); |
| } |
| |
| /** |
| * Switch to scan mode properly with IMS deferring time and Wifi calling. |
| * |
| * IMS deregistration is done before reaching the timeout. |
| */ |
| @Test |
| public void switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingOnImsUnregistered() |
| throws Exception { |
| setUpVoWifiTest(true, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| when(mWifiNative.switchClientInterfaceToScanMode(any(), any())) |
| .thenReturn(true); |
| |
| mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| |
| // Not yet finish IMS deregistration. |
| verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any()); |
| verify(mImsMmTelManager).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt()); |
| |
| // Notify wifi service IMS service is de-registered. |
| assertNotNull(mImsMmTelManagerRegistrationCallback); |
| mImsMmTelManagerRegistrationCallback.onUnregistered(null); |
| assertNotNull(mImsNetworkCallback); |
| mImsNetworkCallback.onLost(null); |
| mLooper.dispatchAll(); |
| |
| // Now Wifi could be switched to scan mode actually. |
| verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE); |
| verify(mImsMmTelManager).unregisterImsRegistrationCallback( |
| any(RegistrationManager.RegistrationCallback.class)); |
| assertNull(mImsMmTelManagerRegistrationCallback); |
| assertNull(mImsNetworkCallback); |
| verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt()); |
| } |
| |
| /** |
| * Switch to scan mode properly with IMS deferring time and Wifi calling. |
| * |
| * Network lost before IMS deregistration is done. The wifi should be still available |
| * until IMS is de-registered or time out. |
| */ |
| @Test |
| public void switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingOnNetworkLostFirst() |
| throws Exception { |
| setUpVoWifiTest(true, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| when(mWifiNative.switchClientInterfaceToScanMode(any(), any())) |
| .thenReturn(true); |
| |
| mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| |
| // Not yet finish IMS deregistration. |
| verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any()); |
| verify(mImsMmTelManager).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt()); |
| |
| // Notify wifi service network lost |
| assertNotNull(mImsNetworkCallback); |
| mImsNetworkCallback.onLost(null); |
| mLooper.dispatchAll(); |
| |
| // Since IMS service is not de-registered yet, wifi should be available. |
| moveTimeForward(1000); |
| mLooper.dispatchAll(); |
| verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any()); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt()); |
| |
| // Notify wifi service IMS service is de-registered. |
| assertNotNull(mImsMmTelManagerRegistrationCallback); |
| mImsMmTelManagerRegistrationCallback.onUnregistered(null); |
| mLooper.dispatchAll(); |
| |
| // Now Wifi could be switched to scan mode actually. |
| verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE); |
| verify(mImsMmTelManager).unregisterImsRegistrationCallback( |
| any(RegistrationManager.RegistrationCallback.class)); |
| assertNull(mImsMmTelManagerRegistrationCallback); |
| assertNull(mImsNetworkCallback); |
| verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt()); |
| } |
| |
| /** |
| * Switch to scan mode properly with IMS deferring time and Wifi calling. |
| * |
| * IMS deregistration is done before reaching the timeout. |
| */ |
| @Test |
| public void switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingOnImsRegistered() |
| throws Exception { |
| setUpVoWifiTest(true, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| when(mWifiNative.switchClientInterfaceToScanMode(any(), any())) |
| .thenReturn(true); |
| |
| mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| |
| // Not yet finish IMS deregistration. |
| verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any()); |
| verify(mImsMmTelManager).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt()); |
| |
| // Notify wifi service IMS service is de-registered. |
| assertNotNull(mImsMmTelManagerRegistrationCallback); |
| mImsMmTelManagerRegistrationCallback.onRegistered(0); |
| mLooper.dispatchAll(); |
| |
| // Now Wifi could be switched to scan mode actually. |
| verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE); |
| verify(mImsMmTelManager).unregisterImsRegistrationCallback( |
| any(RegistrationManager.RegistrationCallback.class)); |
| assertNull(mImsMmTelManagerRegistrationCallback); |
| verify(mWifiMetrics).noteWifiOff(eq(true), eq(false), anyInt()); |
| } |
| |
| /** |
| * Switch to scan mode properly with IMS deferring time and Wifi calling. |
| * |
| * IMS deregistration is NOT done before reaching the timeout. |
| */ |
| @Test |
| public void switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingTimedOut() |
| throws Exception { |
| setUpVoWifiTest(true, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| when(mWifiNative.switchClientInterfaceToScanMode(any(), any())) |
| .thenReturn(true); |
| |
| mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| |
| verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any()); |
| verify(mImsMmTelManager).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| |
| // 1/2 deferring time passed, should be still waiting for the callback. |
| moveTimeForward(TEST_WIFI_OFF_DEFERRING_TIME_MS / 2); |
| mLooper.dispatchAll(); |
| verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any()); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt()); |
| |
| // Exceeding the timeout, wifi should be stopped. |
| moveTimeForward(TEST_WIFI_OFF_DEFERRING_TIME_MS / 2 + 1000); |
| mLooper.dispatchAll(); |
| verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE); |
| verify(mImsMmTelManager).unregisterImsRegistrationCallback( |
| any(RegistrationManager.RegistrationCallback.class)); |
| assertNull(mImsMmTelManagerRegistrationCallback); |
| verify(mWifiMetrics).noteWifiOff(eq(true), eq(true), anyInt()); |
| } |
| |
| /** |
| * Switch to scan mode properly with IMS deferring time and Wifi calling. |
| * |
| * IMS deregistration is NOT done before reaching the timeout with multiple stop calls. |
| */ |
| @Test |
| public void |
| switchToScanOnlyModeWithWifiOffDeferringTimeAndWifiCallingTimedOutMultipleSwitch() |
| throws Exception { |
| setUpVoWifiTest(true, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| when(mWifiNative.switchClientInterfaceToScanMode(any(), any())) |
| .thenReturn(true); |
| |
| mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| |
| verify(mImsMmTelManager).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| |
| mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| // should not register another listener. |
| verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any()); |
| verify(mImsMmTelManager, times(1)).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt()); |
| |
| // Exceeding the timeout, wifi should be stopped. |
| moveTimeForward(TEST_WIFI_OFF_DEFERRING_TIME_MS + 1000); |
| mLooper.dispatchAll(); |
| verify(mWifiNative).switchClientInterfaceToScanMode(TEST_INTERFACE_NAME, TEST_WORKSOURCE); |
| verify(mImsMmTelManager).unregisterImsRegistrationCallback( |
| any(RegistrationManager.RegistrationCallback.class)); |
| assertNull(mImsMmTelManagerRegistrationCallback); |
| verify(mWifiMetrics).noteWifiOff(eq(true), eq(true), anyInt()); |
| } |
| |
| /** |
| * Stay at connected mode with IMS deferring time and Wifi calling |
| * when the target state is not ROLE_CLIENT_SCAN_ONLY. |
| * |
| * Simulate a user toggle wifi multiple times before doing wifi stop and stay at |
| * ON position. |
| */ |
| @Test |
| public void |
| stayAtConnectedModeWithWifiOffDeferringTimeAndWifiCallingTimedOutMultipleSwitch() |
| throws Exception { |
| setUpVoWifiTest(true, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| when(mWifiNative.switchClientInterfaceToScanMode(any(), any())) |
| .thenReturn(true); |
| |
| mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| mClientModeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| mClientModeManager.setRole(ROLE_CLIENT_SCAN_ONLY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| mClientModeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| |
| verify(mImsMmTelManager).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| |
| // should not register another listener. |
| verify(mWifiNative, never()).switchClientInterfaceToScanMode(any(), any()); |
| verify(mImsMmTelManager, times(1)).registerImsRegistrationCallback( |
| any(Executor.class), |
| any(RegistrationManager.RegistrationCallback.class)); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt()); |
| |
| // Exceeding the timeout, wifi should NOT be stopped. |
| moveTimeForward(TEST_WIFI_OFF_DEFERRING_TIME_MS + 1000); |
| mLooper.dispatchAll(); |
| verify(mWifiNative, never()).switchClientInterfaceToScanMode( |
| TEST_INTERFACE_NAME, TEST_WORKSOURCE); |
| verify(mImsMmTelManager).unregisterImsRegistrationCallback( |
| any(RegistrationManager.RegistrationCallback.class)); |
| assertNull(mImsMmTelManagerRegistrationCallback); |
| verify(mWifiMetrics, never()).noteWifiOff(anyBoolean(), anyBoolean(), anyInt()); |
| } |
| |
| /** |
| * ClientMode stop properly with IMS deferring time without WifiCalling. |
| */ |
| @Test |
| public void clientModeStopWithImsManagerException() throws Exception { |
| setUpVoWifiTest(true, |
| TEST_WIFI_OFF_DEFERRING_TIME_MS); |
| when(mImsMmTelManager.isAvailable(anyInt(), anyInt())) |
| .thenThrow(new RuntimeException("Test Runtime Exception")); |
| |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mContext, mListener); |
| setUpSystemServiceForContext(); |
| mClientModeManager.stop(); |
| mLooper.dispatchAll(); |
| when(mClientModeImpl.hasQuit()).thenReturn(true); |
| mClientModeManager.onClientModeImplQuit(); |
| verify(mListener).onStopped(mClientModeManager); |
| |
| verifyConnectModeNotificationsForCleanShutdown(WIFI_STATE_ENABLED); |
| |
| verify(mImsMmTelManager, never()).registerImsRegistrationCallback(any(), any()); |
| verify(mImsMmTelManager, never()).unregisterImsRegistrationCallback(any()); |
| verify(mWifiMetrics).noteWifiOff(eq(false), eq(false), anyInt()); |
| |
| // on an explicit stop, we should not trigger the callback |
| verifyNoMoreInteractions(mListener); |
| } |
| |
| /** |
| * ClientMode starts up in connect mode and then change connectivity roles. |
| */ |
| @Test |
| public void clientInConnectModeChangeRoles() throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mListener); |
| |
| // Set the same role again, no-op. |
| assertEquals(ActiveModeManager.ROLE_CLIENT_PRIMARY, mClientModeManager.getRole()); |
| mClientModeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| verify(mWifiNative).replaceStaIfaceRequestorWs( |
| eq(TEST_INTERFACE_NAME), same(TEST_WORKSOURCE)); |
| verify(mListener, never()).onRoleChanged(any()); // no callback sent. |
| |
| // Change the connectivity role. |
| ActiveModeManager.Listener<ConcreteClientModeManager> newListener = |
| mock(ActiveModeManager.Listener.class); |
| mClientModeManager.setRole( |
| ActiveModeManager.ROLE_CLIENT_SECONDARY_TRANSIENT, TEST_WORKSOURCE, newListener); |
| mLooper.dispatchAll(); |
| verify(mWifiNative, times(2)).replaceStaIfaceRequestorWs( |
| eq(TEST_INTERFACE_NAME), same(TEST_WORKSOURCE)); |
| verify(newListener).onRoleChanged(mClientModeManager); // callback sent on new listener. |
| verifyNoMoreInteractions(mListener); // no callback sent on older listener. |
| } |
| |
| @Test |
| public void clientInConnectModeChangeRolesNewWorkSource_WifiNativeFailed_noCallback() |
| throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| reset(mListener); |
| |
| when(mWifiNative.replaceStaIfaceRequestorWs(TEST_INTERFACE_NAME, TEST_WORKSOURCE2)) |
| .thenReturn(false); |
| |
| // set new mode with new WorkSource |
| mClientModeManager.setRole(ROLE_CLIENT_SECONDARY_TRANSIENT, TEST_WORKSOURCE2); |
| mLooper.dispatchAll(); |
| |
| verify(mWifiNative).replaceStaIfaceRequestorWs( |
| eq(TEST_INTERFACE_NAME), same(TEST_WORKSOURCE2)); |
| // no callback sent since replaceStaIfaceRequestorWs failed |
| verify(mListener, never()).onRoleChanged(any()); |
| } |
| |
| @Test |
| public void setRoleBeforeInvokingListener() throws Exception { |
| when(mWifiNative.setupInterfaceForClientInScanMode(any(), any())) |
| .thenReturn(TEST_INTERFACE_NAME); |
| when(mWifiNative.switchClientInterfaceToConnectivityMode(any(), any())) |
| .thenReturn(true); |
| |
| doAnswer(new AnswerWithArguments() { |
| public void answer(ActiveModeManager clientModeManager) throws Exception { |
| assertEquals(ROLE_CLIENT_SCAN_ONLY, clientModeManager.getRole()); |
| } |
| }).when(mListener).onStarted(mClientModeManager); |
| mClientModeManager = createClientModeManager(ROLE_CLIENT_SCAN_ONLY); |
| mLooper.dispatchAll(); |
| |
| ActiveModeManager.ClientRole lastRole = mClientModeManager.getRole(); |
| assertEquals(ROLE_CLIENT_SCAN_ONLY, lastRole); |
| assertNull(mClientModeManager.getPreviousRole()); |
| |
| verify(mWifiNative).setupInterfaceForClientInScanMode( |
| mInterfaceCallbackCaptor.capture(), eq(TEST_WORKSOURCE)); |
| mInterfaceCallbackCaptor.getValue().onUp(TEST_INTERFACE_NAME); |
| mLooper.dispatchAll(); |
| verify(mListener).onStarted(mClientModeManager); // callback sent. |
| |
| // Change to connectivity role. |
| long testChangeRoleTimestamp = 12234455L; |
| when(mClock.getElapsedSinceBootMillis()).thenReturn(testChangeRoleTimestamp); |
| doAnswer(new AnswerWithArguments() { |
| public void answer(ActiveModeManager clientModeManager) throws Exception { |
| assertEquals(ActiveModeManager.ROLE_CLIENT_PRIMARY, clientModeManager.getRole()); |
| } |
| }).when(mListener).onRoleChanged(mClientModeManager); |
| mClientModeManager.setRole(ActiveModeManager.ROLE_CLIENT_PRIMARY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| verify(mListener).onRoleChanged(mClientModeManager); // callback sent. |
| |
| // Verify the role is changed and previousRole is updated. |
| assertEquals("Should equal previous role", lastRole, |
| mClientModeManager.getPreviousRole()); |
| assertEquals("The role change timestamp should match", testChangeRoleTimestamp, |
| mClientModeManager.getLastRoleChangeSinceBootMs()); |
| } |
| |
| @Test |
| public void propagateSettingsToClientModeImpl() throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| verify(mWifiInjector).makeClientModeImpl(any(), any(), eq(false)); |
| verify(mClientModeImpl).setShouldReduceNetworkScore(false); |
| |
| mClientModeManager.enableVerboseLogging(true); |
| verify(mClientModeImpl).enableVerboseLogging(true); |
| |
| mClientModeManager.enableVerboseLogging(false); |
| verify(mClientModeImpl).enableVerboseLogging(false); |
| |
| mClientModeManager.setShouldReduceNetworkScore(true); |
| verify(mClientModeImpl).setShouldReduceNetworkScore(true); |
| |
| mClientModeManager.setShouldReduceNetworkScore(false); |
| verify(mClientModeImpl, times(2)).setShouldReduceNetworkScore(false); |
| } |
| |
| @Test |
| public void propagateConnectedWifiScorerToPrimaryClientModeImpl() throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| |
| IBinder iBinder = mock(IBinder.class); |
| IWifiConnectedNetworkScorer iScorer = mock(IWifiConnectedNetworkScorer.class); |
| mClientModeManager.setWifiConnectedNetworkScorer(iBinder, iScorer); |
| verify(mClientModeImpl).setWifiConnectedNetworkScorer(iBinder, iScorer); |
| |
| mClientModeManager.clearWifiConnectedNetworkScorer(); |
| verify(mClientModeImpl).clearWifiConnectedNetworkScorer(); |
| |
| mClientModeManager.setWifiConnectedNetworkScorer(iBinder, iScorer); |
| verify(mClientModeImpl, times(2)).setWifiConnectedNetworkScorer(iBinder, iScorer); |
| } |
| |
| @Test |
| public void updateConnectModeStateInAllRoles() throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| mClientModeManager.setRole(ROLE_CLIENT_SECONDARY_TRANSIENT, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| mClientModeManager.stop(); |
| // disabling broadcast wasn't sent out (since role is secondary) |
| verify(mContext, never()).sendStickyBroadcastAsUser( |
| argThat(intent -> |
| intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1) |
| == WifiManager.WIFI_STATE_DISABLING), |
| any()); |
| // but wifi state was updated (should be updated no matter the role) |
| assertEquals(WifiManager.WIFI_STATE_DISABLING, mClientModeManager.syncGetWifiState()); |
| } |
| |
| @Test |
| public void changeRoleResetsSettings() throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| |
| verify(mClientModeImpl).setShouldReduceNetworkScore(false); |
| |
| mClientModeManager.setRole(ROLE_CLIENT_SECONDARY_TRANSIENT, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| |
| // reset upon role change |
| verify(mClientModeImpl, times(2)).setShouldReduceNetworkScore(false); |
| } |
| |
| @Test |
| public void sameRoleDoesntResetsSettings() throws Exception { |
| startClientInConnectModeAndVerifyEnabled(); |
| |
| verify(mClientModeImpl).setShouldReduceNetworkScore(false); |
| |
| mClientModeManager.setRole(ROLE_CLIENT_PRIMARY, TEST_WORKSOURCE); |
| mLooper.dispatchAll(); |
| |
| // no role change, no reset |
| verify(mClientModeImpl).setShouldReduceNetworkScore(false); |
| } |
| } |