NetworkControllerWifiTest.java revision d57f3247766d7e5f2a5c2cbe7be6d241526a9eba
1package com.android.systemui.statusbar.policy;
2
3import android.content.Intent;
4import android.graphics.drawable.Drawable;
5import android.net.NetworkCapabilities;
6import android.net.NetworkInfo;
7import android.net.NetworkKey;
8import android.net.RssiCurve;
9import android.net.ScoredNetwork;
10import android.net.WifiKey;
11import android.net.wifi.WifiInfo;
12import android.net.wifi.WifiManager;
13import android.net.wifi.WifiNetworkScoreCache;
14import android.os.Bundle;
15import android.provider.Settings;
16import android.support.test.InstrumentationRegistry;
17import android.support.test.runner.AndroidJUnit4;
18import android.test.suitebuilder.annotation.SmallTest;
19
20import com.android.settingslib.Utils;
21import com.android.systemui.statusbar.policy.NetworkController.IconState;
22import com.android.systemui.utils.FakeSettingsProvider.SettingOverrider;
23
24import org.junit.Test;
25import org.junit.runner.RunWith;
26import org.mockito.ArgumentCaptor;
27import org.mockito.Matchers;
28import org.mockito.Mockito;
29import org.mockito.invocation.InvocationOnMock;
30import org.mockito.stubbing.Answer;
31
32import static junit.framework.Assert.assertEquals;
33import static junit.framework.Assert.assertNotNull;
34
35import static org.mockito.Matchers.any;
36import static org.mockito.Matchers.anyBoolean;
37import static org.mockito.Matchers.anyInt;
38import static org.mockito.Mockito.doAnswer;
39import static org.mockito.Mockito.mock;
40import static org.mockito.Mockito.verify;
41import static org.mockito.Mockito.when;
42
43import java.util.Arrays;
44import java.util.ArrayList;
45import java.util.List;
46import java.util.concurrent.CountDownLatch;
47import java.util.concurrent.TimeUnit;
48
49@SmallTest
50@RunWith(AndroidJUnit4.class)
51public class NetworkControllerWifiTest extends NetworkControllerBaseTest {
52    // These match the constants in WifiManager and need to be kept up to date.
53    private static final int MIN_RSSI = -100;
54    private static final int MAX_RSSI = -55;
55
56    private static final int LATCH_TIMEOUT = 2000;
57    private static final String TEST_SSID = "\"Test SSID\"";
58    private static final String TEST_BSSID = "00:00:00:00:00:00";
59
60    private final List<NetworkKey> mRequestedKeys = new ArrayList<>();
61    private CountDownLatch mRequestScoresLatch;
62
63    private SettingOverrider mSettingsOverrider;
64
65    @Test
66    public void testWifiIcon() {
67        String testSsid = "Test SSID";
68        setWifiEnabled(true);
69        verifyLastWifiIcon(false, WifiIcons.WIFI_NO_NETWORK);
70
71        setWifiState(true, testSsid);
72        verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[0][0]);
73
74        for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
75            setWifiLevel(testLevel);
76
77            setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true);
78            verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
79            setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, false, true);
80            verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[0][testLevel]);
81        }
82    }
83
84    @Test
85    public void testBadgedWifiIcon() throws Exception {
86        int testLevel = 1;
87        RssiCurve mockBadgeCurve = mock(RssiCurve.class);
88        Bundle attr = new Bundle();
89        attr.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve);
90        ScoredNetwork score =
91                new ScoredNetwork(
92                        new NetworkKey(new WifiKey(TEST_SSID, TEST_BSSID)),
93                        null,
94                        false /* meteredHint */,
95                        attr);
96
97        // Enable scoring
98        mSettingsOverrider = mContext.getSettingsProvider().acquireOverridesBuilder(this)
99                .addSetting("global", Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, "1")
100                .build();
101
102        setupNetworkScoreManager();
103        mRequestScoresLatch = new CountDownLatch(1);
104        setWifiEnabled(true);
105        setWifiState(true, TEST_SSID, TEST_BSSID);
106        mRequestScoresLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
107
108        when(mockBadgeCurve.lookupScore(anyInt())).thenReturn((byte) ScoredNetwork.BADGING_SD);
109
110        ArgumentCaptor<WifiNetworkScoreCache> scoreCacheCaptor =
111                ArgumentCaptor.forClass(WifiNetworkScoreCache.class);
112        verify(mMockNetworkScoreManager).registerNetworkScoreCache(
113                anyInt(),
114                scoreCacheCaptor.capture(),
115                Matchers.anyInt());
116        scoreCacheCaptor.getValue().updateScores(Arrays.asList(score));
117
118        setWifiLevel(testLevel);
119        NetworkController.SignalCallback mockCallback =
120                mock(NetworkController.SignalCallback.class);
121        mNetworkController.addCallback(mockCallback);
122
123        ArgumentCaptor<IconState> iconState = ArgumentCaptor.forClass(IconState.class);
124        Mockito.verify(mockCallback).setWifiIndicators(
125                anyBoolean(), iconState.capture(), any(), anyBoolean(), anyBoolean(), any());
126
127        assertEquals("Badged Wifi Resource is set",
128                Utils.WIFI_PIE_FOR_BADGING[testLevel],
129                iconState.getValue().icon);
130        assertEquals("SD Badge is set",
131                Utils.getWifiBadgeResource(ScoredNetwork.BADGING_SD),
132                iconState.getValue().iconOverlay);
133
134        mSettingsOverrider.release();
135    }
136
137    private void setupNetworkScoreManager() {
138        // Capture requested keys and count down latch if present
139        doAnswer(
140                new Answer<Boolean>() {
141                    @Override
142                    public Boolean answer(InvocationOnMock input) {
143                        if (mRequestScoresLatch != null) {
144                            mRequestScoresLatch.countDown();
145                        }
146                        NetworkKey[] keys = (NetworkKey[]) input.getArguments()[0];
147                        for (NetworkKey key : keys) {
148                            mRequestedKeys.add(key);
149                        }
150                        return true;
151                    }
152                }).when(mMockNetworkScoreManager).requestScores(Matchers.<NetworkKey[]>any());
153    }
154
155    @Test
156    public void testQsWifiIcon() {
157        String testSsid = "Test SSID";
158
159        setWifiEnabled(false);
160        verifyLastQsWifiIcon(false, false, WifiIcons.QS_WIFI_NO_NETWORK, null);
161
162        setWifiEnabled(true);
163        verifyLastQsWifiIcon(true, false, WifiIcons.QS_WIFI_NO_NETWORK, null);
164
165        setWifiState(true, testSsid);
166        for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
167            setWifiLevel(testLevel);
168
169            setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true);
170            verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[1][testLevel],
171                    testSsid);
172            setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, false, true);
173            verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[0][testLevel],
174                    testSsid);
175        }
176    }
177
178    @Test
179    public void testQsDataDirection() {
180        // Setup normal connection
181        String testSsid = "Test SSID";
182        int testLevel = 2;
183        setWifiEnabled(true);
184        setWifiState(true, testSsid);
185        setWifiLevel(testLevel);
186        setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true);
187        verifyLastQsWifiIcon(true, true,
188                WifiIcons.QS_WIFI_SIGNAL_STRENGTH[1][testLevel], testSsid);
189
190        // Set to different activity state first to ensure a callback happens.
191        setWifiActivity(WifiManager.DATA_ACTIVITY_IN);
192
193        setWifiActivity(WifiManager.DATA_ACTIVITY_NONE);
194        verifyLastQsDataDirection(false, false);
195        setWifiActivity(WifiManager.DATA_ACTIVITY_IN);
196        verifyLastQsDataDirection(true, false);
197        setWifiActivity(WifiManager.DATA_ACTIVITY_OUT);
198        verifyLastQsDataDirection(false, true);
199        setWifiActivity(WifiManager.DATA_ACTIVITY_INOUT);
200        verifyLastQsDataDirection(true, true);
201    }
202
203    @Test
204    public void testRoamingIconDuringWifi() {
205        // Setup normal connection
206        String testSsid = "\"Test SSID\"";
207        int testLevel = 2;
208        setWifiEnabled(true);
209        setWifiState(true, testSsid);
210        setWifiLevel(testLevel);
211        setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true);
212        verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
213
214        setupDefaultSignal();
215        setGsmRoaming(true);
216        // Still be on wifi though.
217        setConnectivity(NetworkCapabilities.TRANSPORT_WIFI, true, true);
218        verifyLastMobileDataIndicators(true,
219                TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][DEFAULT_LEVEL],
220                TelephonyIcons.ROAMING_ICON);
221    }
222
223    protected void setWifiActivity(int activity) {
224        // TODO: Not this, because this variable probably isn't sticking around.
225        mNetworkController.mWifiSignalController.setActivity(activity);
226    }
227
228    protected void setWifiLevel(int level) {
229        float amountPerLevel = (MAX_RSSI - MIN_RSSI) / (WifiIcons.WIFI_LEVEL_COUNT - 1);
230        int rssi = (int)(MIN_RSSI + level * amountPerLevel);
231        // Put RSSI in the middle of the range.
232        rssi += amountPerLevel / 2;
233        Intent i = new Intent(WifiManager.RSSI_CHANGED_ACTION);
234        i.putExtra(WifiManager.EXTRA_NEW_RSSI, rssi);
235        mNetworkController.onReceive(mContext, i);
236    }
237
238    protected void setWifiEnabled(boolean enabled) {
239        Intent i = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
240        i.putExtra(WifiManager.EXTRA_WIFI_STATE,
241                enabled ? WifiManager.WIFI_STATE_ENABLED : WifiManager.WIFI_STATE_DISABLED);
242        mNetworkController.onReceive(mContext, i);
243    }
244
245    protected void setWifiState(boolean connected, String ssid) {
246        setWifiState(connected, ssid, null);
247    }
248
249    protected void setWifiState(boolean connected, String ssid, String bssid) {
250        Intent i = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
251        NetworkInfo networkInfo = Mockito.mock(NetworkInfo.class);
252        Mockito.when(networkInfo.isConnected()).thenReturn(connected);
253
254        WifiInfo wifiInfo = Mockito.mock(WifiInfo.class);
255        Mockito.when(wifiInfo.getSSID()).thenReturn(ssid);
256        if (bssid != null) {
257            Mockito.when(wifiInfo.getBSSID()).thenReturn(bssid);
258        }
259
260        i.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
261        i.putExtra(WifiManager.EXTRA_WIFI_INFO, wifiInfo);
262        mNetworkController.onReceive(mContext, i);
263    }
264
265    protected void verifyLastQsDataDirection(boolean in, boolean out) {
266        ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class);
267        ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class);
268
269        Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
270                anyBoolean(), any(), any(), inArg.capture(), outArg.capture(), any());
271        assertEquals("WiFi data in, in quick settings", in, (boolean) inArg.getValue());
272        assertEquals("WiFi data out, in quick settings", out, (boolean) outArg.getValue());
273    }
274
275    protected void verifyLastQsWifiIcon(boolean enabled, boolean connected, int icon,
276            String description) {
277        ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
278        ArgumentCaptor<Boolean> enabledArg = ArgumentCaptor.forClass(Boolean.class);
279        ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class);
280
281        Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
282                enabledArg.capture(), any(), iconArg.capture(), anyBoolean(),
283                anyBoolean(),  descArg.capture());
284        IconState iconState = iconArg.getValue();
285        assertEquals("WiFi enabled, in quick settings", enabled, (boolean) enabledArg.getValue());
286        assertEquals("WiFi connected, in quick settings", connected, iconState.visible);
287        assertEquals("WiFi signal, in quick settings", icon, iconState.icon);
288        assertEquals("WiFI desc (ssid), in quick settings", description, descArg.getValue());
289    }
290
291    protected void verifyLastWifiIcon(boolean visible, int icon) {
292        ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
293
294        Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
295                anyBoolean(), iconArg.capture(), any(), anyBoolean(), anyBoolean(),
296                any());
297        IconState iconState = iconArg.getValue();
298        assertEquals("WiFi visible, in status bar", visible, iconState.visible);
299        assertEquals("WiFi signal, in status bar", icon, iconState.icon);
300    }
301}
302