ScanOnlyModeManagerTest.java revision 7dadc4d68ea820779ec513073347890b842a6f9c
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;
347dadc4d68ea820779ec513073347890b842a6f9cEtan Cohenimport static org.mockito.Mockito.verify;
357dadc4d68ea820779ec513073347890b842a6f9cEtan Cohenimport static org.mockito.Mockito.verifyNoMoreInteractions;
367dadc4d68ea820779ec513073347890b842a6f9cEtan Cohenimport static org.mockito.Mockito.when;
3726db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
38d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silbersteinimport android.content.Context;
39d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silbersteinimport android.content.Intent;
40d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silbersteinimport android.os.UserHandle;
41eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silbersteinimport android.os.test.TestLooper;
427f2a1e30dd5d14320ffc7b185ac25fdb79fe52b0Etan Cohenimport android.support.test.filters.SmallTest;
43aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein
44eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silbersteinimport org.junit.Before;
45eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silbersteinimport org.junit.Test;
46aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silbersteinimport org.mockito.ArgumentCaptor;
47ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbachimport org.mockito.InOrder;
4826db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silbersteinimport org.mockito.Mock;
4926db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silbersteinimport org.mockito.MockitoAnnotations;
50eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
51eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein/**
52eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein * Unit tests for {@link ScanOnlyModeManager}.
53eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein */
54eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein@SmallTest
55eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silbersteinpublic class ScanOnlyModeManagerTest {
56eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    private static final String TAG = "ScanOnlyModeManagerTest";
5726db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    private static final String TEST_INTERFACE_NAME = "testif0";
58aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    private static final String OTHER_INTERFACE_NAME = "notTestIf";
59eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
60eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    TestLooper mLooper;
61eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
62eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    ScanOnlyModeManager mScanOnlyModeManager;
63eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
64d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein    @Mock Context mContext;
6526db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    @Mock WifiMetrics mWifiMetrics;
6626db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    @Mock WifiNative mWifiNative;
679f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein    @Mock ScanOnlyModeManager.Listener mListener;
68d09f94469f1e130ba4b6a4b48976b13558267ed3Rebecca Silberstein    @Mock WifiMonitor mWifiMonitor;
697eac1e20f0afc510535cd6de1024309f1adb9b4eRoshan Pius    @Mock ScanRequestProxy mScanRequestProxy;
70ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    @Mock WakeupController mWakeupController;
71aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein
729189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius    final ArgumentCaptor<WifiNative.StatusListener> mStatusListenerCaptor =
739189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius            ArgumentCaptor.forClass(WifiNative.StatusListener.class);
749189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius    final ArgumentCaptor<WifiNative.InterfaceCallback> mInterfaceCallbackCaptor =
759189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius            ArgumentCaptor.forClass(WifiNative.InterfaceCallback.class);
7626db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
77eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    @Before
78eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    public void setUp() {
7926db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        MockitoAnnotations.initMocks(this);
80eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein        mLooper = new TestLooper();
8126db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
82eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein        mScanOnlyModeManager = createScanOnlyModeManager();
8326db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        mLooper.dispatchAll();
84eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    }
85eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
86eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    private ScanOnlyModeManager createScanOnlyModeManager() {
879f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        return new ScanOnlyModeManager(mContext, mLooper.getLooper(), mWifiNative, mListener,
88ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach                mWifiMetrics, mScanRequestProxy, mWakeupController);
8926db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    }
9026db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
9126db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    private void startScanOnlyModeAndVerifyEnabled() throws Exception {
927dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen        when(mWifiNative.setupInterfaceForClientMode(anyBoolean(), any())).thenReturn(
937dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen                TEST_INTERFACE_NAME);
9426db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        mScanOnlyModeManager.start();
9526db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        mLooper.dispatchAll();
9626db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
979189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius        verify(mWifiNative).registerStatusListener(mStatusListenerCaptor.capture());
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);
106d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        verify(mContext).sendStickyBroadcastAsUser(intentCaptor.capture(),
107d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein                eq(UserHandle.ALL));
108d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein
109d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_ENABLED);
1109f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        checkWifiStateChangeListenerUpdate(WIFI_STATE_ENABLED);
1117eac1e20f0afc510535cd6de1024309f1adb9b4eRoshan Pius        verify(mScanRequestProxy, atLeastOnce()).enableScanningForHiddenNetworks(false);
112d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein    }
113d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein
114d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein    private void checkWifiScanStateChangedBroadcast(Intent intent, int expectedCurrentState) {
115d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        String action = intent.getAction();
116d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        assertEquals(WIFI_SCAN_AVAILABLE, action);
117d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        int currentState = intent.getIntExtra(EXTRA_SCAN_AVAILABLE, WIFI_STATE_UNKNOWN);
118d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        assertEquals(expectedCurrentState, currentState);
11926db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    }
12026db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
1219f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein    private void checkWifiStateChangeListenerUpdate(int expectedCurrentState) {
1229f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        verify(mListener).onStateChanged(eq(expectedCurrentState));
1239f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein    }
1249f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein
12526db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    /**
12626db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein     * ScanMode start sets up an interface in ClientMode for scanning.
12726db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein     */
12826db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    @Test
129dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    public void scanModeStartAndVerifyEnabled() throws Exception {
13026db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
131eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    }
132eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
133eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    /**
134dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     * ScanMode idle state does not crash when a native status update comes before entering the
135dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     * active state.
136dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     */
137dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    @Test
138dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    public void scanModeNativeUpdateBeforeStartDoesNotCrash() throws Exception {
139dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verify(mWifiNative).registerStatusListener(mStatusListenerCaptor.capture());
140dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
141dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        mStatusListenerCaptor.getValue().onStatusChanged(false);
142dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        mLooper.dispatchAll();
143dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verifyNoMoreInteractions(mContext, mListener);
144dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
145dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verify(mScanRequestProxy, never()).clearScanResults();
146dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    }
147dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
148dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    /**
1499189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius     * ScanMode increments failure metrics when failing to setup client mode.
15026db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein     */
15126db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    @Test
1529189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius    public void detectAndReportErrorWhenSetupForClientWifiNativeFailure() throws Exception {
1537dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen        when(mWifiNative.setupInterfaceForClientMode(anyBoolean(), any())).thenReturn(null);
15426db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        mScanOnlyModeManager.start();
15526db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        mLooper.dispatchAll();
1569f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein
1579f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
1589f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(),
1599f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein                eq(UserHandle.ALL));
1609f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_DISABLED);
1619f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
16226db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    }
16326db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
16426db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    /**
1659f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein     * ScanMode start does not indicate scanning is available when the interface name is empty.
16626db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein     */
16726db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    @Test
1689f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein    public void scanModeStartDoesNotSendScanningActiveWhenClientInterfaceNameIsEmpty()
1699f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein            throws Exception {
1707dadc4d68ea820779ec513073347890b842a6f9cEtan Cohen        when(mWifiNative.setupInterfaceForClientMode(anyBoolean(), any())).thenReturn("");
17126db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        mScanOnlyModeManager.start();
17226db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        mLooper.dispatchAll();
1739f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein
1749f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
1759f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(),
1769f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein                eq(UserHandle.ALL));
1779f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_DISABLED);
1789f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
17926db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    }
18026db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
18126db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    /**
182aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein     * Calling ScanOnlyModeManager.start twice does not crash or restart scan mode.
18326db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein     */
18426db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    @Test
185aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    public void scanOnlyModeStartCalledTwice() throws Exception {
18626db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
1879f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        reset(mWifiNative, mContext);
188aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        mScanOnlyModeManager.start();
189eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein        mLooper.dispatchAll();
1909f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        verifyNoMoreInteractions(mWifiNative, mContext);
191eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    }
192eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein
193eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    /**
194aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein     * ScanMode stop properly cleans up state
19526db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein     */
19626db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    @Test
197aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    public void scanModeStopCleansUpState() throws Exception {
19826db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
199d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        reset(mContext);
200aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        mScanOnlyModeManager.stop();
20126db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein        mLooper.dispatchAll();
202dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        // check when interface management it dynamic
203dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        //verify(mWifiNative).teardownInterface(TEST_INTERFACE_NAME);
204d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
205d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        verify(mContext, atLeastOnce()).sendStickyBroadcastAsUser(intentCaptor.capture(),
206d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein                eq(UserHandle.ALL));
207d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_DISABLED);
2089f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        checkWifiStateChangeListenerUpdate(WIFI_STATE_DISABLED);
2097eac1e20f0afc510535cd6de1024309f1adb9b4eRoshan Pius        verify(mScanRequestProxy).clearScanResults();
21026db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    }
21126db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein
21226db2f08784c3a9b48c63110dded3581d65e4b4eRebecca Silberstein    /**
213dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     * ScanMode properly stops when underlying interface is destroyed.
214dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     */
215dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    @Test
216dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    public void scanModeStopsOnInterfaceDestroyed() throws Exception {
217dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
218dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        reset(mContext);
219dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        mInterfaceCallbackCaptor.getValue().onDestroyed(TEST_INTERFACE_NAME);
220dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        mLooper.dispatchAll();
221dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
222dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verify(mContext).sendStickyBroadcastAsUser(intentCaptor.capture(),
223dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein                eq(UserHandle.ALL));
224dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_DISABLED);
225dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        checkWifiStateChangeListenerUpdate(WIFI_STATE_DISABLED);
226dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verify(mScanRequestProxy).clearScanResults();
227dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    }
228dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
229dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    /**
2309f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein     * Calling stop when ScanMode is not started should not send scan state updates
231eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein     */
232eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    @Test
2339f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein    public void scanModeStopWhenNotStartedDoesNotUpdateScanStateUpdates() throws Exception {
234aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
235aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        mScanOnlyModeManager.stop();
236aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        mLooper.dispatchAll();
2379189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius        reset(mContext, mListener);
238aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein
239aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        // now call stop again
240eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein        mScanOnlyModeManager.stop();
241eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein        mLooper.dispatchAll();
242d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        verify(mContext, never()).sendStickyBroadcastAsUser(any(), any());
2439f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        verify(mListener, never()).onStateChanged(anyInt());
244aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    }
245aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein
246aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    /**
247dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     * Triggering interface down when ScanOnlyMode is active properly exits the active state and
248dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     * reports an error.
249aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein     */
250aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    @Test
251aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    public void scanModeStartedStopsWhenInterfaceDown() throws Exception {
252aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
253d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        reset(mContext);
2549189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius        mInterfaceCallbackCaptor.getValue().onDown(TEST_INTERFACE_NAME);
255aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        mLooper.dispatchAll();
256d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
257dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verify(mContext).sendStickyBroadcastAsUser(intentCaptor.capture(),
258dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein                                                   eq(UserHandle.ALL));
259d73ee2ef749ecc25bc9de791ecf4462c549ad417Rebecca Silberstein        checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_DISABLED);
260dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
2619f82f5e706adffbad03a95cce8399c59898297bbRebecca Silberstein        checkWifiStateChangeListenerUpdate(WIFI_STATE_DISABLED);
262dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verify(mScanRequestProxy).clearScanResults();
263aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    }
264aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein
265aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein    /**
266dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     * Triggering an interface down for a different interface will not exit scan mode.
267dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     */
268dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    @Test
269dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    public void scanModeStartedDoesNotStopOnDownForDifferentIface() throws Exception {
270dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
271dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        reset(mContext, mListener);
272dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        mInterfaceCallbackCaptor.getValue().onDown(OTHER_INTERFACE_NAME);
273dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
274dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        mLooper.dispatchAll();
275dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
276dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verifyNoMoreInteractions(mContext, mListener);
277dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
278dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verify(mScanRequestProxy, never()).clearScanResults();
279dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    }
280dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
281dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
282dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    /**
283dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     * Testing the handling of a WifiNative failure status change notification.
284d09f94469f1e130ba4b6a4b48976b13558267ed3Rebecca Silberstein     */
285d09f94469f1e130ba4b6a4b48976b13558267ed3Rebecca Silberstein    @Test
2869189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius    public void scanModeStartedStopsOnNativeFailure() throws Exception {
2879189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius        startScanOnlyModeAndVerifyEnabled();
2889189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius        reset(mContext);
2899189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius        mStatusListenerCaptor.getValue().onStatusChanged(false);
290aba32c6808bc33bb9164bdc9bc13461abb0fc9e6Rebecca Silberstein        mLooper.dispatchAll();
291d09f94469f1e130ba4b6a4b48976b13558267ed3Rebecca Silberstein        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
292dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verify(mContext).sendStickyBroadcastAsUser(intentCaptor.capture(),
293dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein                                                   eq(UserHandle.ALL));
294dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
295d09f94469f1e130ba4b6a4b48976b13558267ed3Rebecca Silberstein        checkWifiScanStateChangedBroadcast(intentCaptor.getValue(), WIFI_STATE_DISABLED);
296dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        checkWifiStateChangeListenerUpdate(WIFI_STATE_UNKNOWN);
2979189ab6cf9aa4f04e12947f13b1daafed93676a0Roshan Pius        checkWifiStateChangeListenerUpdate(WIFI_STATE_DISABLED);
298dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verify(mScanRequestProxy).clearScanResults();
299dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    }
300dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
301dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    /**
302dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     * WifiNative callback that does not indicate failure should not stop Scan mode.
303dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein     */
304dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    @Test
305dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein    public void scanModeStartedDoesNotStopOnNativeSuccessUpdate() throws Exception {
306dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        startScanOnlyModeAndVerifyEnabled();
307dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        reset(mContext, mListener);
308dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        mStatusListenerCaptor.getValue().onStatusChanged(true);
309dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        mLooper.dispatchAll();
310dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
311dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verifyNoMoreInteractions(mContext, mListener);
312dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein
313dfed3425d98fb3d09cb2d3d4b9d9ab3d45d5f818Rebecca Silberstein        verify(mScanRequestProxy, never()).clearScanResults();
314eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein    }
315ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach
316ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    /**
317ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach     * Entering StartedState starts the WakeupController.
318ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach     */
319ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    @Test
320ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    public void scanModeEnterStartsWakeupController() throws Exception {
321ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        startScanOnlyModeAndVerifyEnabled();
322ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach
323ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        verify(mWakeupController).start();
324ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    }
325ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach
326ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    /**
327ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach     * Exiting StartedState stops the WakeupController.
328ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach     */
329ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    @Test
330ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    public void scanModeExitStopsWakeupController() throws Exception {
331ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        startScanOnlyModeAndVerifyEnabled();
332ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach
333ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        mScanOnlyModeManager.stop();
334ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        mLooper.dispatchAll();
335ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach
336ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        InOrder inOrder = inOrder(mWakeupController);
337ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach
338ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        inOrder.verify(mWakeupController).start();
339ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach        inOrder.verify(mWakeupController).stop();
340ea5fdf86e727701c0472f5e72a45cdbe7e28fdd3Eric Schwarzenbach    }
341eb5ac1b8b78b5a7cfd6f37f8183a548b0e98df90Rebecca Silberstein}
342