1eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein/*
2eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein * Copyright 2018 The Android Open Source Project
3eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein *
4eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein * Licensed under the Apache License, Version 2.0 (the "License");
5eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein * you may not use this file except in compliance with the License.
6eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein * You may obtain a copy of the License at
7eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein *
8eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein *      http://www.apache.org/licenses/LICENSE-2.0
9eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein *
10eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein * Unless required by applicable law or agreed to in writing, software
11eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein * distributed under the License is distributed on an "AS IS" BASIS,
12eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein * See the License for the specific language governing permissions and
14eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein * limitations under the License.
15eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein */
16eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
17eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silbersteinpackage com.android.server.wifi;
18eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
19d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silbersteinimport static android.net.wifi.WifiManager.EXTRA_SCAN_AVAILABLE;
20d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silbersteinimport static android.net.wifi.WifiManager.WIFI_SCAN_AVAILABLE;
21d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silbersteinimport static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
22d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silbersteinimport static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
23d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silbersteinimport static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN;
24d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein
25d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silbersteinimport static org.junit.Assert.assertEquals;
267dadc4d68ea820779ec513073347890b842a6f9cEtan Cohenimport static org.mockito.ArgumentMatchers.anyBoolean;
277dadc4d68ea820779ec513073347890b842a6f9cEtan Cohenimport static org.mockito.Mockito.any;
287dadc4d68ea820779ec513073347890b842a6f9cEtan Cohenimport static org.mockito.Mockito.anyInt;
297dadc4d68ea820779ec513073347890b842a6f9cEtan Cohenimport static org.mockito.Mockito.atLeastOnce;
307dadc4d68ea820779ec513073347890b842a6f9cEtan Cohenimport static org.mockito.Mockito.eq;
317dadc4d68ea820779ec513073347890b842a6f9cEtan Cohenimport static org.mockito.Mockito.inOrder;
327dadc4d68ea820779ec513073347890b842a6f9cEtan Cohenimport static org.mockito.Mockito.never;
337dadc4d68ea820779ec513073347890b842a6f9cEtan Cohenimport static org.mockito.Mockito.reset;
34a7798d5d92a8a324ba8e70148a2601547a138d2eRebecca Silbersteinimport static org.mockito.Mockito.times;
357dadc4d68ea820779ec513073347890b842a6f9cEtan Cohenimport static org.mockito.Mockito.verify;
367dadc4d68ea820779ec513073347890b842a6f9cEtan Cohenimport static org.mockito.Mockito.verifyNoMoreInteractions;
377dadc4d68ea820779ec513073347890b842a6f9cEtan Cohenimport static org.mockito.Mockito.when;
3826db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
39d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silbersteinimport android.content.Context;
40d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silbersteinimport android.content.Intent;
41d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silbersteinimport android.os.UserHandle;
42eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silbersteinimport android.os.test.TestLooper;
437f2a1e30dd5d14320ffc7b185ac25fdb79fe52b0Etan Cohenimport android.support.test.filters.SmallTest;
44aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein
45eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silbersteinimport org.junit.Before;
46eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silbersteinimport org.junit.Test;
47aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silbersteinimport org.mockito.ArgumentCaptor;
48ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbachimport org.mockito.InOrder;
4926db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silbersteinimport org.mockito.Mock;
5026db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silbersteinimport org.mockito.MockitoAnnotations;
51eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
52a7798d5d92a8a324ba8e70148a2601547a138d2eRebecca Silbersteinimport java.util.List;
53a7798d5d92a8a324ba8e70148a2601547a138d2eRebecca Silberstein
54eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein/**
55eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein * Unit tests for {@link ScanOnlyModeManager}.
56eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein */
57eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein@SmallTest
58eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silbersteinpublic class ScanOnlyModeManagerTest {
59eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    private static final String TAG = "ScanOnlyModeManagerTest";
6026db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    private static final String TEST_INTERFACE_NAME = "testif0";
61aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    private static final String OTHER_INTERFACE_NAME = "notTestIf";
62eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
63eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    TestLooper mLooper;
64eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
65eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    ScanOnlyModeManager mScanOnlyModeManager;
66eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
67d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein    @Mock Context mContext;
6826db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    @Mock WifiMetrics mWifiMetrics;
6926db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    @Mock WifiNative mWifiNative;
709f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein    @Mock ScanOnlyModeManager.Listener mListener;
71d09f94469f1e130ba4b6a4b48976b13558267ed3Rebecca Silberstein    @Mock WifiMonitor mWifiMonitor;
727eac1e20f0afc510535cd6de1024309f1adb9b4eRoshan Pius    @Mock ScanRequestProxy mScanRequestProxy;
73ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    @Mock WakeupController mWakeupController;
74aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein
759189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius    final ArgumentCaptor<WifiNative.InterfaceCallback> mInterfaceCallbackCaptor =
769189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius            ArgumentCaptor.forClass(WifiNative.InterfaceCallback.class);
7726db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
78eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    @Before
79eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    public void setUp() {
8026db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        MockitoAnnotations.initMocks(this);
81eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein        mLooper = new TestLooper();
8226db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
83eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein        mScanOnlyModeManager = createScanOnlyModeManager();
8426db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        mLooper.dispatchAll();
85eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    }
86eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
87eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    private ScanOnlyModeManager createScanOnlyModeManager() {
889f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        return new ScanOnlyModeManager(mContext, mLooper.getLooper(), mWifiNative, mListener,
89ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach                mWifiMetrics, mScanRequestProxy, mWakeupController);
9026db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    }
9126db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
9226db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    private void startScanOnlyModeAndVerifyEnabled() throws Exception {
937dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen        when(mWifiNative.setupInterfaceForClientMode(anyBoolean(), any())).thenReturn(
947dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen                TEST_INTERFACE_NAME);
9526db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        mScanOnlyModeManager.start();
9626db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        mLooper.dispatchAll();
9726db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
987dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen        verify(mWifiNative).setupInterfaceForClientMode(eq(true),
997dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen                mInterfaceCallbackCaptor.capture());
100aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein
101aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        // now mark the interface as up
1029189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius        mInterfaceCallbackCaptor.getValue().onUp(TEST_INTERFACE_NAME);
103aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        mLooper.dispatchAll();
104aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein
105d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
106a7798d5d92a8a324ba8e70148a2601547a138d2eRebecca Silberstein        verify(mContext, times(2)).sendStickyBroadcastAsUser(intentCaptor.capture(),
107d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein                eq(UserHandle.ALL));
108a7798d5d92a8a324ba8e70148a2601547a138d2eRebecca Silberstein        List<Intent> intents = intentCaptor.getAllValues();
109d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein
110a7798d5d92a8a324ba8e70148a2601547a138d2eRebecca Silberstein        checkWifiScanStateChangedBroadcast(intents.get(0), WIFI_STATE_DISABLED);
111a7798d5d92a8a324ba8e70148a2601547a138d2eRebecca Silberstein        checkWifiScanStateChangedBroadcast(intents.get(1), WIFI_STATE_ENABLED);
1129f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        checkWifiStateChangeListenerUpdate(WIFI_STATE_ENABLED);
1131b60f40a00afc38da4587ae275702d758bf66332Rebecca Silberstein        verify(mScanRequestProxy, atLeastOnce()).clearScanResults();
1147eac1e20f0afc510535cd6de1024309f1adb9b4eRoshan Pius        verify(mScanRequestProxy, atLeastOnce()).enableScanningForHiddenNetworks(false);
115d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein    }
116d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein
117d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein    private void checkWifiScanStateChangedBroadcast(Intent intent, int expectedCurrentState) {
118d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        String action = intent.getAction();
119d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        assertEquals(WIFI_SCAN_AVAILABLE, action);
120d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        int currentState = intent.getIntExtra(EXTRA_SCAN_AVAILABLE, WIFI_STATE_UNKNOWN);
121d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        assertEquals(expectedCurrentState, currentState);
12226db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    }
12326db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
1249f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein    private void checkWifiStateChangeListenerUpdate(int expectedCurrentState) {
1259f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        verify(mListener).onStateChanged(eq(expectedCurrentState));
1269f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein    }
1279f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein
12826db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    /**
12926db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein     * ScanMode start sets up an interface in ClientMode for scanning.
13026db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein     */
13126db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    @Test
132dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    public void scanModeStartAndVerifyEnabled() throws Exception {
13326db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
134eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    }
135eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
136eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    /**
1379f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein     * ScanMode start does not indicate scanning is available when the interface name is empty.
13826db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein     */
13926db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    @Test
1409f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein    public void scanModeStartDoesNotSendScanningActiveWhenClientInterfaceNameIsEmpty()
1419f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein            throws Exception {
1427dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen        when(mWifiNative.setupInterfaceForClientMode(anyBoolean(), any())).thenReturn("");
14326db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        mScanOnlyModeManager.start();
14426db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        mLooper.dispatchAll();
1459f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein
146a7798d5d92a8a324ba8e70148a2601547a138d2eRebecca Silberstein        verify(mContext, never()).sendStickyBroadcastAsUser(any(), eq(UserHandle.ALL));
1479f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
14826db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    }
14926db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
15026db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    /**
151aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein     * Calling ScanOnlyModeManager.start twice does not crash or restart scan mode.
15226db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein     */
15326db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    @Test
154aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    public void scanOnlyModeStartCalledTwice() throws Exception {
15526db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
1569f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        reset(mWifiNative, mContext);
157aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        mScanOnlyModeManager.start();
158eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein        mLooper.dispatchAll();
1599f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        verifyNoMoreInteractions(mWifiNative, mContext);
160eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    }
161eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
162eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    /**
163aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein     * ScanMode stop properly cleans up state
16426db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein     */
16526db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    @Test
166aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    public void scanModeStopCleansUpState() throws Exception {
16726db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
1681b60f40a00afc38da4587ae275702d758bf66332Rebecca Silberstein        reset(mContext, mListener);
169aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        mScanOnlyModeManager.stop();
17026db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        mLooper.dispatchAll();
1711b60f40a00afc38da4587ae275702d758bf66332Rebecca Silberstein        verify(mWifiNative).teardownInterface(TEST_INTERFACE_NAME);
172a7798d5d92a8a324ba8e70148a2601547a138d2eRebecca Silberstein        verify(mContext, never()).sendStickyBroadcastAsUser(any(), eq(UserHandle.ALL));
173f7814ce9117a6622dd1662cbe9396b1684447004Rebecca Silberstein        verifyNoMoreInteractions(mListener);
17426db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    }
17526db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
17626db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    /**
177dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     * ScanMode properly stops when underlying interface is destroyed.
178dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     */
179dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    @Test
180dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    public void scanModeStopsOnInterfaceDestroyed() throws Exception {
181dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
182dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        reset(mContext);
183dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        mInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME);
184dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        mLooper.dispatchAll();
185a7798d5d92a8a324ba8e70148a2601547a138d2eRebecca Silberstein        verify(mContext, never()).sendStickyBroadcastAsUser(any(), eq(UserHandle.ALL));
186dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    }
187dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
188dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    /**
1899f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein     * Calling stop when ScanMode is not started should not send scan state updates
190eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein     */
191eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    @Test
1929f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein    public void scanModeStopWhenNotStartedDoesNotUpdateScanStateUpdates() throws Exception {
193aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
194aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        mScanOnlyModeManager.stop();
195aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        mLooper.dispatchAll();
1969189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius        reset(mContext, mListener);
197aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein
198aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        // now call stop again
199eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein        mScanOnlyModeManager.stop();
200eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein        mLooper.dispatchAll();
201d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        verify(mContext, never()).sendStickyBroadcastAsUser(any(), any());
2029f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        verify(mListener, never()).onStateChanged(anyInt());
203aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    }
204aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein
205aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    /**
206dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     * Triggering interface down when ScanOnlyMode is active properly exits the active state and
207dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     * reports an error.
208aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein     */
209aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    @Test
210aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    public void scanModeStartedStopsWhenInterfaceDown() throws Exception {
211aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
212d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        reset(mContext);
2139189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius        mInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME);
214aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        mLooper.dispatchAll();
215a7798d5d92a8a324ba8e70148a2601547a138d2eRebecca Silberstein        verify(mContext, never()).sendStickyBroadcastAsUser(any(), eq(UserHandle.ALL));
216dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
217dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verify(mScanRequestProxy).clearScanResults();
218aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    }
219aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein
220aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    /**
221dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     * Triggering an interface down for a different interface will not exit scan mode.
222dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     */
223dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    @Test
224dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    public void scanModeStartedDoesNotStopOnDownForDifferentIface() throws Exception {
225dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
2261b60f40a00afc38da4587ae275702d758bf66332Rebecca Silberstein        reset(mContext, mListener, mScanRequestProxy);
227dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        mInterfaceCallbackCaptor.getValue().onDown(OTHER_INTERFACE_NAME);
228dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
229dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        mLooper.dispatchAll();
230dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
231dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verifyNoMoreInteractions(mContext, mListener);
232dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
233dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verify(mScanRequestProxy, never()).clearScanResults();
234dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    }
235dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
236ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    /**
237080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein     * Verify that onDestroyed after scan mode is stopped doesn't trigger a callback.
238080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein     */
239080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein    @Test
240080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein    public void noCallbackOnInterfaceDestroyedWhenAlreadyStopped() throws Exception {
241080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
242080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein
243080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein        reset(mListener);
244080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein
245080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein        mScanOnlyModeManager.stop();
246080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein        mLooper.dispatchAll();
247080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein
248080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein        // now trigger interface destroyed and make sure callback doesn't get called
249080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein        mInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME);
250080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein        mLooper.dispatchAll();
251080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein
252080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein        verifyNoMoreInteractions(mListener);
253080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein    }
254080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein
255080c2f856866353e300ec431acc106eb076bfeb6Rebecca Silberstein    /**
256ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach     * Entering StartedState starts the WakeupController.
257ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach     */
258ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    @Test
259ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    public void scanModeEnterStartsWakeupController() throws Exception {
260ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        startScanOnlyModeAndVerifyEnabled();
261ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach
262ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        verify(mWakeupController).start();
263ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    }
264ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach
265ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    /**
266ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach     * Exiting StartedState stops the WakeupController.
267ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach     */
268ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    @Test
269ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    public void scanModeExitStopsWakeupController() throws Exception {
270ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        startScanOnlyModeAndVerifyEnabled();
271ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach
272ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        mScanOnlyModeManager.stop();
273ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        mLooper.dispatchAll();
274ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach
2751b60f40a00afc38da4587ae275702d758bf66332Rebecca Silberstein        InOrder inOrder = inOrder(mWakeupController, mWifiNative, mListener);
276ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach
277ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        inOrder.verify(mWakeupController).start();
278ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        inOrder.verify(mWakeupController).stop();
2791b60f40a00afc38da4587ae275702d758bf66332Rebecca Silberstein        inOrder.verify(mWifiNative).teardownInterface(eq(TEST_INTERFACE_NAME));
280ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    }
281eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein}
282