1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.wifi.aware;
18
19import static org.hamcrest.core.IsEqual.equalTo;
20import static org.hamcrest.core.IsNull.nullValue;
21import static org.mockito.ArgumentMatchers.any;
22import static org.mockito.ArgumentMatchers.eq;
23import static org.mockito.Mockito.inOrder;
24import static org.mockito.Mockito.verifyNoMoreInteractions;
25import static org.mockito.Mockito.when;
26
27import android.hardware.wifi.V1_0.IWifiNanIface;
28import android.hardware.wifi.V1_0.IfaceType;
29import android.hardware.wifi.V1_0.WifiStatus;
30import android.hardware.wifi.V1_0.WifiStatusCode;
31
32import com.android.server.wifi.HalDeviceManager;
33
34import org.junit.Before;
35import org.junit.Rule;
36import org.junit.Test;
37import org.junit.rules.ErrorCollector;
38import org.mockito.ArgumentCaptor;
39import org.mockito.InOrder;
40import org.mockito.Mock;
41import org.mockito.MockitoAnnotations;
42
43/**
44 * Unit test harness for WifiAwareNativeManager.
45 */
46public class WifiAwareNativeManagerTest {
47    private WifiAwareNativeManager mDut;
48    @Mock private WifiAwareStateManager mWifiAwareStateManagerMock;
49    @Mock private HalDeviceManager mHalDeviceManager;
50    @Mock private WifiAwareNativeCallback mWifiAwareNativeCallback;
51    @Mock private IWifiNanIface mWifiNanIfaceMock;
52    private ArgumentCaptor<HalDeviceManager.ManagerStatusListener> mManagerStatusListenerCaptor =
53            ArgumentCaptor.forClass(HalDeviceManager.ManagerStatusListener.class);
54    private ArgumentCaptor<HalDeviceManager.InterfaceDestroyedListener>
55            mDestroyedListenerCaptor = ArgumentCaptor.forClass(
56            HalDeviceManager.InterfaceDestroyedListener.class);
57    private ArgumentCaptor<HalDeviceManager.InterfaceAvailableForRequestListener>
58            mAvailListenerCaptor = ArgumentCaptor.forClass(
59            HalDeviceManager.InterfaceAvailableForRequestListener.class);
60    private InOrder mInOrder;
61    @Rule public ErrorCollector collector = new ErrorCollector();
62
63    private WifiStatus mStatusOk;
64
65    @Before
66    public void setUp() throws Exception {
67        MockitoAnnotations.initMocks(this);
68
69        mStatusOk = new WifiStatus();
70        mStatusOk.code = WifiStatusCode.SUCCESS;
71
72        when(mWifiNanIfaceMock.registerEventCallback(any())).thenReturn(mStatusOk);
73
74        mDut = new WifiAwareNativeManager(mWifiAwareStateManagerMock,
75                mHalDeviceManager, mWifiAwareNativeCallback);
76        mDut.start();
77
78        mInOrder = inOrder(mWifiAwareStateManagerMock, mHalDeviceManager);
79    }
80
81    /**
82     * Test the control flow of the manager:
83     * 1. onStatusChange (ready/started)
84     * 2. null NAN iface
85     * 3. onAvailableForRequest
86     * 4. non-null NAN iface -> enableUsage
87     * 5. onStatusChange (!started) -> disableUsage
88     * 6. onStatusChange (ready/started)
89     * 7. non-null NAN iface -> enableUsage
90     * 8. onDestroyed -> disableUsage
91     * 9. onStatusChange (!started)
92     */
93    @Test
94    public void testControlFlow() {
95        // configure HalDeviceManager as ready/wifi started
96        when(mHalDeviceManager.isReady()).thenReturn(true);
97        when(mHalDeviceManager.isStarted()).thenReturn(true);
98
99        // validate (and capture) that register manage status callback
100        mInOrder.verify(mHalDeviceManager).registerStatusListener(
101                mManagerStatusListenerCaptor.capture(), any());
102
103        // 1 & 2 onStatusChange (ready/started): validate that trying to get a NAN interface
104        // (make sure gets a NULL)
105        when(mHalDeviceManager.createNanIface(any(), any())).thenReturn(null);
106
107        mManagerStatusListenerCaptor.getValue().onStatusChanged();
108        mInOrder.verify(mHalDeviceManager).registerInterfaceAvailableForRequestListener(
109                eq(IfaceType.NAN), mAvailListenerCaptor.capture(), any());
110        mAvailListenerCaptor.getValue().onAvailableForRequest();
111
112        mInOrder.verify(mHalDeviceManager).createNanIface(
113                mDestroyedListenerCaptor.capture(), any());
114        collector.checkThat("null interface", mDut.getWifiNanIface(), nullValue());
115
116        // 3 & 4 onAvailableForRequest + non-null return value: validate that enables usage
117        when(mHalDeviceManager.createNanIface(any(), any())).thenReturn(mWifiNanIfaceMock);
118
119        mAvailListenerCaptor.getValue().onAvailableForRequest();
120
121        mInOrder.verify(mHalDeviceManager).createNanIface(
122                mDestroyedListenerCaptor.capture(), any());
123        mInOrder.verify(mWifiAwareStateManagerMock).enableUsage();
124        collector.checkThat("non-null interface", mDut.getWifiNanIface(),
125                equalTo(mWifiNanIfaceMock));
126
127        // 5 onStatusChange (!started): disable usage
128        when(mHalDeviceManager.isStarted()).thenReturn(false);
129        mManagerStatusListenerCaptor.getValue().onStatusChanged();
130
131        mInOrder.verify(mWifiAwareStateManagerMock).disableUsage();
132        collector.checkThat("null interface", mDut.getWifiNanIface(), nullValue());
133
134        // 6 & 7 onStatusChange (ready/started) + non-null NAN interface: enable usage
135        when(mHalDeviceManager.isStarted()).thenReturn(true);
136        mManagerStatusListenerCaptor.getValue().onStatusChanged();
137
138        mManagerStatusListenerCaptor.getValue().onStatusChanged();
139        mInOrder.verify(mHalDeviceManager).registerInterfaceAvailableForRequestListener(
140                eq(IfaceType.NAN), mAvailListenerCaptor.capture(), any());
141        mAvailListenerCaptor.getValue().onAvailableForRequest();
142
143        mInOrder.verify(mHalDeviceManager).createNanIface(
144                mDestroyedListenerCaptor.capture(), any());
145        mInOrder.verify(mWifiAwareStateManagerMock).enableUsage();
146        collector.checkThat("non-null interface", mDut.getWifiNanIface(),
147                equalTo(mWifiNanIfaceMock));
148
149        // 8 onDestroyed: disable usage
150        mDestroyedListenerCaptor.getValue().onDestroyed();
151
152        mInOrder.verify(mWifiAwareStateManagerMock).disableUsage();
153        collector.checkThat("null interface", mDut.getWifiNanIface(), nullValue());
154
155        // 9 onStatusChange (!started): nothing more happens
156        when(mHalDeviceManager.isStarted()).thenReturn(false);
157        mManagerStatusListenerCaptor.getValue().onStatusChanged();
158
159        verifyNoMoreInteractions(mWifiAwareStateManagerMock);
160    }
161}
162