• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.settings.wifi;
17 
18 import static android.support.test.InstrumentationRegistry.getInstrumentation;
19 import static android.support.test.espresso.Espresso.onView;
20 import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
21 import static android.support.test.espresso.assertion.ViewAssertions.matches;
22 import static android.support.test.espresso.matcher.ViewMatchers.Visibility.VISIBLE;
23 import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
24 import static android.support.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
25 import static android.support.test.espresso.matcher.ViewMatchers.withId;
26 import static android.support.test.espresso.matcher.ViewMatchers.withText;
27 
28 import static com.google.common.truth.Truth.assertThat;
29 
30 import static org.hamcrest.Matchers.allOf;
31 import static org.hamcrest.Matchers.not;
32 import static org.hamcrest.Matchers.startsWith;
33 import static org.mockito.Mockito.atMost;
34 import static org.mockito.Mockito.times;
35 import static org.mockito.Mockito.verify;
36 import static org.mockito.Mockito.when;
37 
38 import android.app.Activity;
39 import android.app.Fragment;
40 import android.content.Context;
41 import android.content.Intent;
42 import android.net.ConnectivityManager;
43 import android.net.NetworkInfo;
44 import android.net.wifi.WifiConfiguration;
45 import android.net.wifi.WifiInfo;
46 import android.net.wifi.WifiManager;
47 import android.net.wifi.WifiSsid;
48 import android.provider.Settings;
49 import android.support.test.InstrumentationRegistry;
50 import android.support.test.rule.ActivityTestRule;
51 import android.support.test.runner.AndroidJUnit4;
52 
53 import com.android.settings.Settings.WifiSettingsActivity;
54 import com.android.settingslib.utils.ThreadUtils;
55 import com.android.settingslib.wifi.AccessPoint;
56 import com.android.settingslib.wifi.TestAccessPointBuilder;
57 import com.android.settingslib.wifi.WifiTracker;
58 import com.android.settingslib.wifi.WifiTracker.WifiListener;
59 import com.android.settingslib.wifi.WifiTrackerFactory;
60 
61 import com.google.common.collect.Lists;
62 
63 import org.junit.Before;
64 import org.junit.Ignore;
65 import org.junit.Rule;
66 import org.junit.Test;
67 import org.junit.runner.RunWith;
68 import org.mockito.Mock;
69 import org.mockito.MockitoAnnotations;
70 
71 import java.util.List;
72 
73 @RunWith(AndroidJUnit4.class)
74 public class WifiSettingsUiTest {
75     private static final String TEST_SSID = "\"Test Ssid\"";
76     private static final String TEST_UNQUOTED_SSID = "Test Ssid";
77     private static final String TEST_BSSID = "0a:08:5c:67:89:00";
78     private static final int TEST_RSSI = 123;
79     private static final int TEST_NETWORK_ID = 1;
80 
81     // Keys used to lookup resources by name (see the resourceId/resourceString helper methods).
82     private static final String ID = "id";
83     private static final String STRING = "string";
84     private static final String WIFI_CONFIGURE_SETTINGS_PREFERENCE_TITLE =
85             "wifi_configure_settings_preference_title";
86     private static final String WIFI_SAVED_ACCESS_POINTS_LABEL = "wifi_saved_access_points_label";
87     private static final String WIFI_EMPTY_LIST_WIFI_OFF = "wifi_empty_list_wifi_off";
88     private static final String WIFI_DISPLAY_STATUS_CONNECTED = "wifi_display_status_connected";
89     private static final String WIFI_PASSWORD = "wifi_password";
90     private static final String WIFI_SHOW_PASSWORD = "wifi_show_password";
91     private static final String PASSWORD_LAYOUT = "password_layout";
92     private static final String PASSWORD = "password";
93 
94     @Mock
95     private WifiTracker mWifiTracker;
96     @Mock
97     private WifiManager mWifiManager;
98     private Context mContext;
99     private WifiListener mWifiListener;
100 
101     @Rule
102     public ActivityTestRule<WifiSettingsActivity> mActivityRule =
103             new ActivityTestRule<>(WifiSettingsActivity.class, true);
104 
105     @Before
setUp()106     public void setUp() {
107         MockitoAnnotations.initMocks(this);
108         mContext = InstrumentationRegistry.getTargetContext();
109         WifiTrackerFactory.setTestingWifiTracker(mWifiTracker);
110         when(mWifiTracker.getManager()).thenReturn(mWifiManager);
111     }
112 
113     /**
114      * Helper to get around the problem that directly accessing settings resource id's from
115      * com.android.settings.R via R.(type).(name) (eg R.id.password or
116      * R.string.wifi_configure_settings_preference_title) may not work due to mismatched resource
117      * ids. See b/37714546 and b/63546650.
118      */
resourceId(String type, String name)119     private int resourceId(String type, String name) {
120         return mContext.getResources().getIdentifier(name, type, mContext.getPackageName());
121     }
122 
123     /** Similar to {@link #resourceId}, but for accessing R.string.<name> values. */
resourceString(String name)124     private String resourceString(String name) {
125         return mContext.getResources().getString(resourceId(STRING, name));
126     }
127 
setupConnectedAccessPoint()128     private void setupConnectedAccessPoint() {
129         WifiConfiguration config = new WifiConfiguration();
130         config.SSID = TEST_SSID;
131         config.BSSID = TEST_BSSID;
132         config.networkId = TEST_NETWORK_ID;
133         WifiInfo wifiInfo = new WifiInfo();
134         wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(TEST_UNQUOTED_SSID));
135         wifiInfo.setBSSID(TEST_BSSID);
136         wifiInfo.setRssi(TEST_RSSI);
137         wifiInfo.setNetworkId(TEST_NETWORK_ID);
138         NetworkInfo networkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, null, null);
139         networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
140         AccessPoint accessPoint = new AccessPoint(mContext, config);
141         accessPoint.update(config, wifiInfo, networkInfo);
142 
143         assertThat(accessPoint.getSsidStr()).isEqualTo(TEST_UNQUOTED_SSID);
144         assertThat(accessPoint.getBssid()).isEqualTo(TEST_BSSID);
145         assertThat(accessPoint.getNetworkInfo()).isNotNull();
146         assertThat(accessPoint.isActive()).isTrue();
147         assertThat(accessPoint.getSettingsSummary()).isEqualTo(
148                 resourceString(WIFI_DISPLAY_STATUS_CONNECTED));
149 
150         when(mWifiTracker.getAccessPoints()).thenReturn(
151                 Lists.asList(accessPoint, new AccessPoint[]{}));
152     }
153 
154     /** Launch the activity via an Intent with a String extra. */
launchActivity(String extraName, String extraValue)155     private void launchActivity(String extraName, String extraValue) {
156         Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
157         if (extraName != null && extraValue != null) {
158             intent.putExtra(extraName, extraValue);
159         }
160         mActivityRule.launchActivity(intent);
161 
162         verify(mWifiTracker).getManager();
163 
164         List<Fragment> fragments = mActivityRule.getActivity().getFragmentManager().getFragments();
165         assertThat(fragments.size()).isEqualTo(1);
166         mWifiListener = (WifiSettings) fragments.get(0);
167         assertThat(mWifiListener).isNotNull();
168     }
169 
170     /** Helper to launch the activity with no extra. */
launchActivity()171     private void launchActivity() {
172         launchActivity(null, null);
173     }
174 
setWifiState(int wifiState)175     private void setWifiState(int wifiState) {
176         when(mWifiManager.getWifiState()).thenReturn(wifiState);
177         when(mWifiManager.isWifiEnabled()).thenReturn(wifiState == WifiManager.WIFI_STATE_ENABLED);
178     }
179 
callOnWifiStateChanged(int state)180     private void callOnWifiStateChanged(int state) {
181         mActivityRule.getActivity().getMainThreadHandler()
182                 .post(() -> mWifiListener.onWifiStateChanged(state));
183     }
184 
185     @Test
launchActivityShouldSucceed()186     public void launchActivityShouldSucceed() {
187         launchActivity();
188     }
189 
190     @Test
shouldShowWifiPreferences()191     public void shouldShowWifiPreferences() {
192         launchActivity();
193 
194         onView(withText(resourceId(STRING, WIFI_CONFIGURE_SETTINGS_PREFERENCE_TITLE))).check(
195                 matches(isDisplayed()));
196     }
197 
198     @Test
noSavedNetworks_wifiEnabled_shouldNotShowSavedNetworksButton()199     public void noSavedNetworks_wifiEnabled_shouldNotShowSavedNetworksButton() {
200         setWifiState(WifiManager.WIFI_STATE_ENABLED);
201         when(mWifiTracker.getNumSavedNetworks()).thenReturn(0);
202 
203         launchActivity();
204 
205         onView(withText(resourceId(STRING, WIFI_SAVED_ACCESS_POINTS_LABEL))).check(
206                 matches(not(isDisplayed())));
207     }
208 
209     @Test
noSavedNetworks_wifiDisabled_shouldNotShowSavedNetworksButton()210     public void noSavedNetworks_wifiDisabled_shouldNotShowSavedNetworksButton() {
211         setWifiState(WifiManager.WIFI_STATE_DISABLED);
212         when(mWifiTracker.getNumSavedNetworks()).thenReturn(0);
213 
214         launchActivity();
215 
216         onView(withText(resourceId(STRING, WIFI_SAVED_ACCESS_POINTS_LABEL))).check(
217                 doesNotExist());
218     }
219 
220     @Test
savedNetworksExist_shouldShowSavedNetworksButton()221     public void savedNetworksExist_shouldShowSavedNetworksButton() {
222         setWifiState(WifiManager.WIFI_STATE_ENABLED);
223         when(mWifiTracker.getNumSavedNetworks()).thenReturn(1);
224 
225         launchActivity();
226 
227         onView(allOf(withText(resourceId(STRING, WIFI_SAVED_ACCESS_POINTS_LABEL)),
228                 withEffectiveVisibility(VISIBLE))).check(matches(isDisplayed()));
229     }
230 
231     @Test
onDisableWifi_seeOffMessage()232     public void onDisableWifi_seeOffMessage() {
233         setWifiState(WifiManager.WIFI_STATE_DISABLED);
234 
235         launchActivity();
236         callOnWifiStateChanged(WifiManager.WIFI_STATE_DISABLED);
237 
238         onView(withText(startsWith(resourceString(WIFI_EMPTY_LIST_WIFI_OFF)))).check(
239                 matches(isDisplayed()));
240     }
241 
242     @Test
onEnableWifi_shouldNotSeeOffMessage()243     public void onEnableWifi_shouldNotSeeOffMessage() {
244         setWifiState(WifiManager.WIFI_STATE_ENABLED);
245 
246         launchActivity();
247         callOnWifiStateChanged(WifiManager.WIFI_STATE_ENABLED);
248 
249         onView(withText(startsWith(resourceString(WIFI_EMPTY_LIST_WIFI_OFF)))).check(
250                 doesNotExist());
251     }
252 
253     @Test
onConnected_shouldSeeConnectedMessage()254     public void onConnected_shouldSeeConnectedMessage() {
255         setWifiState(WifiManager.WIFI_STATE_ENABLED);
256         setupConnectedAccessPoint();
257         when(mWifiTracker.isConnected()).thenReturn(true);
258 
259         launchActivity();
260 
261         onView(withText(resourceString(WIFI_DISPLAY_STATUS_CONNECTED))).check(
262                 matches(isDisplayed()));
263     }
264 
265     @Test
changingSecurityStateOnApShouldNotCauseMultipleListItems()266     public void changingSecurityStateOnApShouldNotCauseMultipleListItems() {
267         setWifiState(WifiManager.WIFI_STATE_ENABLED);
268         TestAccessPointBuilder builder = new TestAccessPointBuilder(mContext)
269                 .setSsid(TEST_SSID)
270                 .setSecurity(AccessPoint.SECURITY_NONE)
271                 .setRssi(TEST_RSSI);
272         AccessPoint open = builder.build();
273 
274         builder.setSecurity(AccessPoint.SECURITY_EAP);
275         AccessPoint eap = builder.build();
276 
277         builder.setSecurity(AccessPoint.SECURITY_WEP);
278         AccessPoint wep = builder.build();
279 
280         // Return a different security state each time getAccessPoints is invoked
281         when(mWifiTracker.getAccessPoints())
282                 .thenReturn(Lists.newArrayList(open))
283                 .thenReturn(Lists.newArrayList(eap))
284                 .thenReturn(Lists.newArrayList(wep));
285 
286         launchActivity();
287 
288         onView(withText(TEST_SSID)).check(matches(isDisplayed()));
289 
290         ThreadUtils.postOnMainThread(() -> mWifiListener.onAccessPointsChanged());
291         onView(withText(TEST_SSID)).check(matches(isDisplayed()));
292 
293         ThreadUtils.postOnMainThread(() -> mWifiListener.onAccessPointsChanged());
294         onView(withText(TEST_SSID)).check(matches(isDisplayed()));
295     }
296 
297     @Test
wrongPasswordSavedNetwork()298     public void wrongPasswordSavedNetwork() {
299         setWifiState(WifiManager.WIFI_STATE_ENABLED);
300 
301         // Set up an AccessPoint that is disabled due to incorrect password.
302         WifiConfiguration config = new WifiConfiguration();
303         config.SSID = TEST_SSID;
304         config.BSSID = TEST_BSSID;
305         config.networkId = TEST_NETWORK_ID;
306         config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
307 
308         WifiConfiguration.NetworkSelectionStatus selectionStatus =
309                 new WifiConfiguration.NetworkSelectionStatus();
310         selectionStatus.setNetworkSelectionDisableReason(
311                 WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD);
312         selectionStatus.setNetworkSelectionStatus(
313                 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
314         config.setNetworkSelectionStatus(selectionStatus);
315 
316         WifiInfo wifiInfo = new WifiInfo();
317         wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(TEST_UNQUOTED_SSID));
318         wifiInfo.setBSSID(TEST_BSSID);
319         wifiInfo.setRssi(TEST_RSSI);
320         wifiInfo.setNetworkId(TEST_NETWORK_ID);
321         AccessPoint accessPoint = new AccessPoint(mContext, config);
322         accessPoint.update(config, wifiInfo, null);
323 
324         // Make sure we've set up our access point correctly.
325         assertThat(accessPoint.getSsidStr()).isEqualTo(TEST_UNQUOTED_SSID);
326         assertThat(accessPoint.getBssid()).isEqualTo(TEST_BSSID);
327         assertThat(accessPoint.isActive()).isFalse();
328         assertThat(accessPoint.getConfig()).isNotNull();
329         WifiConfiguration.NetworkSelectionStatus networkStatus =
330                 accessPoint.getConfig().getNetworkSelectionStatus();
331         assertThat(networkStatus).isNotNull();
332         assertThat(networkStatus.isNetworkEnabled()).isFalse();
333         assertThat(networkStatus.getNetworkSelectionDisableReason()).isEqualTo(
334                 WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD);
335 
336         when(mWifiTracker.getAccessPoints()).thenReturn(Lists.newArrayList(accessPoint));
337         launchActivity(WifiSettings.EXTRA_START_CONNECT_SSID, accessPoint.getSsidStr());
338 
339         // Make sure that the password dialog is visible.
340         onView(withText(resourceId(STRING, WIFI_PASSWORD))).check(matches(isDisplayed()));
341         onView(withText(resourceId(STRING, WIFI_SHOW_PASSWORD))).check(matches(isDisplayed()));
342         onView(withId(resourceId(ID, PASSWORD_LAYOUT))).check(matches(isDisplayed()));
343         onView(withId(resourceId(ID, PASSWORD))).check(matches(isDisplayed()));
344     }
345 
346     @Ignore("b/73796195")
347     @Test
onConnectedChanged_shouldNotFetchAPs()348     public void onConnectedChanged_shouldNotFetchAPs() {
349         setWifiState(WifiManager.WIFI_STATE_ENABLED);
350         when(mWifiTracker.isConnected()).thenReturn(true);
351 
352         launchActivity();
353 
354         verify(mWifiTracker, times(1)).getAccessPoints();
355         onView(withText(WIFI_DISPLAY_STATUS_CONNECTED)).check(matches(isDisplayed()));
356 
357         // Invoke onConnectedChanged
358         when(mWifiTracker.isConnected()).thenReturn(false);
359         mWifiListener.onConnectedChanged();
360 
361         // Verify no additional call to getAccessPoints
362         getInstrumentation().waitForIdleSync();
363         verify(mWifiTracker, times(1)).getAccessPoints();
364     }
365 }
366