1 /*
2  * Copyright (C) 2019 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 com.android.settings.wifi.WifiConfigUiBase2.MODE_CONNECT;
19 import static com.android.settings.wifi.WifiConfigUiBase2.MODE_MODIFY;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import static org.mockito.ArgumentMatchers.any;
24 import static org.mockito.ArgumentMatchers.anyBoolean;
25 import static org.mockito.ArgumentMatchers.anyInt;
26 import static org.mockito.ArgumentMatchers.eq;
27 import static org.mockito.Mockito.doNothing;
28 import static org.mockito.Mockito.doReturn;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.spy;
31 import static org.mockito.Mockito.times;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when;
34 
35 import android.app.Activity;
36 import android.content.ContentResolver;
37 import android.content.Context;
38 import android.content.Intent;
39 import android.content.res.Resources;
40 import android.net.wifi.WifiConfiguration;
41 import android.net.wifi.WifiManager;
42 import android.os.Bundle;
43 import android.os.PowerManager;
44 import android.os.UserManager;
45 import android.provider.Settings;
46 import android.view.ContextMenu;
47 import android.view.View;
48 
49 import androidx.fragment.app.FragmentActivity;
50 import androidx.preference.Preference;
51 import androidx.preference.PreferenceManager;
52 import androidx.preference.PreferenceScreen;
53 import androidx.recyclerview.widget.RecyclerView;
54 
55 import com.android.settings.R;
56 import com.android.settings.datausage.DataUsagePreference;
57 import com.android.settings.testutils.shadow.ShadowDataUsageUtils;
58 import com.android.settings.testutils.shadow.ShadowFragment;
59 import com.android.settingslib.wifi.LongPressWifiEntryPreference;
60 import com.android.wifitrackerlib.WifiEntry;
61 import com.android.wifitrackerlib.WifiPickerTracker;
62 
63 import org.junit.Before;
64 import org.junit.Test;
65 import org.junit.runner.RunWith;
66 import org.mockito.Mock;
67 import org.mockito.MockitoAnnotations;
68 import org.robolectric.RobolectricTestRunner;
69 import org.robolectric.RuntimeEnvironment;
70 import org.robolectric.annotation.Config;
71 import org.robolectric.shadows.ShadowToast;
72 
73 @RunWith(RobolectricTestRunner.class)
74 public class WifiSettings2Test {
75 
76     private static final int NUM_NETWORKS = 4;
77     private static final String FAKE_URI_STRING = "fakeuri";
78 
79     @Mock
80     private PowerManager mPowerManager;
81     @Mock
82     private WifiManager mWifiManager;
83     @Mock
84     private DataUsagePreference mDataUsagePreference;
85     private Context mContext;
86     private WifiSettings2 mWifiSettings2;
87     @Mock
88     private WifiPickerTracker mMockWifiPickerTracker;
89     @Mock
90     private PreferenceManager mPreferenceManager;
91 
92     @Before
setUp()93     public void setUp() {
94         MockitoAnnotations.initMocks(this);
95         mContext = spy(RuntimeEnvironment.application);
96 
97         mWifiSettings2 = spy(new WifiSettings2());
98         doReturn(mContext).when(mWifiSettings2).getContext();
99         doReturn(mPreferenceManager).when(mWifiSettings2).getPreferenceManager();
100         doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
101         doReturn(mWifiManager).when(mContext).getSystemService(WifiManager.class);
102         doReturn(mContext).when(mPreferenceManager).getContext();
103         mWifiSettings2.mAddWifiNetworkPreference = new AddWifiNetworkPreference(mContext);
104         mWifiSettings2.mSavedNetworksPreference = new Preference(mContext);
105         mWifiSettings2.mConfigureWifiSettingsPreference = new Preference(mContext);
106         mWifiSettings2.mWifiPickerTracker = mMockWifiPickerTracker;
107         mWifiSettings2.mWifiManager = mWifiManager;
108     }
109 
110     @Test
addNetworkFragmentSendResult_onActivityResult_shouldHandleEvent()111     public void addNetworkFragmentSendResult_onActivityResult_shouldHandleEvent() {
112         final WifiSettings2 wifiSettings2 = spy(new WifiSettings2());
113         final Intent intent = new Intent();
114         doNothing().when(wifiSettings2).handleAddNetworkRequest(anyInt(), any(Intent.class));
115 
116         wifiSettings2.onActivityResult(WifiSettings2.ADD_NETWORK_REQUEST, Activity.RESULT_OK,
117                 intent);
118 
119         verify(wifiSettings2).handleAddNetworkRequest(anyInt(), any(Intent.class));
120     }
121 
122     @Test
setAdditionalSettingsSummaries_hasSavedNetwork_preferenceVisible()123     public void setAdditionalSettingsSummaries_hasSavedNetwork_preferenceVisible() {
124         when(mMockWifiPickerTracker.getNumSavedNetworks()).thenReturn(NUM_NETWORKS);
125         when(mMockWifiPickerTracker.getNumSavedSubscriptions()).thenReturn(0 /* count */);
126 
127         mWifiSettings2.setAdditionalSettingsSummaries();
128 
129         assertThat(mWifiSettings2.mSavedNetworksPreference.isVisible()).isTrue();
130         assertThat(mWifiSettings2.mSavedNetworksPreference.getSummary()).isEqualTo(
131                 mContext.getResources().getQuantityString(
132                         R.plurals.wifi_saved_access_points_summary,
133                         NUM_NETWORKS, NUM_NETWORKS));
134     }
135 
136     @Test
setAdditionalSettingsSummaries_hasSavedPasspointNetwork_preferenceVisible()137     public void setAdditionalSettingsSummaries_hasSavedPasspointNetwork_preferenceVisible() {
138         when(mMockWifiPickerTracker.getNumSavedNetworks()).thenReturn(0 /* count */);
139         when(mMockWifiPickerTracker.getNumSavedSubscriptions()).thenReturn(NUM_NETWORKS);
140 
141         mWifiSettings2.setAdditionalSettingsSummaries();
142 
143         assertThat(mWifiSettings2.mSavedNetworksPreference.isVisible()).isTrue();
144         assertThat(mWifiSettings2.mSavedNetworksPreference.getSummary()).isEqualTo(
145                 mContext.getResources().getQuantityString(
146                         R.plurals.wifi_saved_passpoint_access_points_summary,
147                         NUM_NETWORKS, NUM_NETWORKS));
148     }
149 
150     @Test
setAdditionalSettingsSummaries_hasTwoKindsSavedNetwork_preferenceVisible()151     public void setAdditionalSettingsSummaries_hasTwoKindsSavedNetwork_preferenceVisible() {
152         when(mMockWifiPickerTracker.getNumSavedNetworks()).thenReturn(NUM_NETWORKS);
153         when(mMockWifiPickerTracker.getNumSavedSubscriptions()).thenReturn(NUM_NETWORKS);
154 
155         mWifiSettings2.setAdditionalSettingsSummaries();
156 
157         assertThat(mWifiSettings2.mSavedNetworksPreference.isVisible()).isTrue();
158         assertThat(mWifiSettings2.mSavedNetworksPreference.getSummary()).isEqualTo(
159                 mContext.getResources().getQuantityString(
160                         R.plurals.wifi_saved_all_access_points_summary,
161                         NUM_NETWORKS*2, NUM_NETWORKS*2));
162     }
163 
164     @Test
setAdditionalSettingsSummaries_noSavedNetwork_preferenceInvisible()165     public void setAdditionalSettingsSummaries_noSavedNetwork_preferenceInvisible() {
166         when(mMockWifiPickerTracker.getNumSavedNetworks()).thenReturn(0 /* count */);
167         when(mMockWifiPickerTracker.getNumSavedSubscriptions()).thenReturn(0 /* count */);
168 
169         mWifiSettings2.setAdditionalSettingsSummaries();
170 
171         assertThat(mWifiSettings2.mSavedNetworksPreference.isVisible()).isFalse();
172     }
173 
174     @Test
setAdditionalSettingsSummaries_wifiWakeupEnabled_displayOn()175     public void setAdditionalSettingsSummaries_wifiWakeupEnabled_displayOn() {
176         final ContentResolver contentResolver = mContext.getContentResolver();
177         when(mWifiManager.isAutoWakeupEnabled()).thenReturn(true);
178         when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true);
179         Settings.Global.putInt(contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0);
180         when(mPowerManager.isPowerSaveMode()).thenReturn(false);
181 
182         mWifiSettings2.setAdditionalSettingsSummaries();
183 
184         assertThat(mWifiSettings2.mConfigureWifiSettingsPreference.getSummary()).isEqualTo(
185                 mContext.getString(R.string.wifi_configure_settings_preference_summary_wakeup_on));
186     }
187 
188     @Test
setAdditionalSettingsSummaries_wifiWakeupDisabled_displayOff()189     public void setAdditionalSettingsSummaries_wifiWakeupDisabled_displayOff() {
190         final ContentResolver contentResolver = mContext.getContentResolver();
191         when(mWifiManager.isAutoWakeupEnabled()).thenReturn(false);
192 
193         mWifiSettings2.setAdditionalSettingsSummaries();
194 
195         assertThat(mWifiSettings2.mConfigureWifiSettingsPreference.getSummary()).isEqualTo(
196                 mContext.getString(R.string.wifi_configure_settings_preference_summary_wakeup_off));
197     }
198 
199     @Test
checkAddWifiNetworkPrefernce_preferenceVisible()200     public void checkAddWifiNetworkPrefernce_preferenceVisible() {
201         assertThat(mWifiSettings2.mAddWifiNetworkPreference.isVisible()).isTrue();
202         assertThat(mWifiSettings2.mAddWifiNetworkPreference.getTitle()).isEqualTo(
203                 mContext.getString(R.string.wifi_add_network));
204     }
205 
setUpForOnCreate()206     private void setUpForOnCreate() {
207         final FragmentActivity activity = mock(FragmentActivity.class);
208         when(mWifiSettings2.getActivity()).thenReturn(activity);
209         final Resources.Theme theme = mContext.getTheme();
210         when(activity.getTheme()).thenReturn(theme);
211         UserManager userManager = mock(UserManager.class);
212         when(activity.getSystemService(Context.USER_SERVICE))
213                 .thenReturn(userManager);
214 
215         when(mWifiSettings2.findPreference(WifiSettings2.PREF_KEY_DATA_USAGE))
216                 .thenReturn(mDataUsagePreference);
217     }
218 
219     @Test
220     @Config(shadows = {ShadowDataUsageUtils.class, ShadowFragment.class})
checkDataUsagePreference_perferenceInvisibleIfWifiNotSupported()221     public void checkDataUsagePreference_perferenceInvisibleIfWifiNotSupported() {
222         setUpForOnCreate();
223         ShadowDataUsageUtils.IS_WIFI_SUPPORTED = false;
224 
225         mWifiSettings2.onCreate(Bundle.EMPTY);
226 
227         verify(mDataUsagePreference).setVisible(false);
228     }
229 
230     @Test
231     @Config(shadows = {ShadowDataUsageUtils.class, ShadowFragment.class})
checkDataUsagePreference_perferenceVisibleIfWifiSupported()232     public void checkDataUsagePreference_perferenceVisibleIfWifiSupported() {
233         setUpForOnCreate();
234         ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true;
235 
236         mWifiSettings2.onCreate(Bundle.EMPTY);
237 
238         verify(mDataUsagePreference).setVisible(true);
239         verify(mDataUsagePreference).setTemplate(any(), eq(0) /*subId*/, eq(null) /*service*/);
240     }
241 
242     @Test
onCreateAdapter_hasStableIdsTrue()243     public void onCreateAdapter_hasStableIdsTrue() {
244         final PreferenceScreen preferenceScreen = mock(PreferenceScreen.class);
245         when(preferenceScreen.getContext()).thenReturn(mContext);
246 
247         RecyclerView.Adapter adapter = mWifiSettings2.onCreateAdapter(preferenceScreen);
248 
249         assertThat(adapter.hasStableIds()).isTrue();
250     }
251 
252     @Test
onCreateContextMenu_shouldHaveForgetAndDisconnectMenuForConnectedWifiEntry()253     public void onCreateContextMenu_shouldHaveForgetAndDisconnectMenuForConnectedWifiEntry() {
254         final FragmentActivity activity = mock(FragmentActivity.class);
255         when(activity.getApplicationContext()).thenReturn(mContext);
256         when(mWifiSettings2.getActivity()).thenReturn(activity);
257 
258         final WifiEntry wifiEntry = mock(WifiEntry.class);
259         when(wifiEntry.canDisconnect()).thenReturn(true);
260         when(wifiEntry.canForget()).thenReturn(true);
261         when(wifiEntry.isSaved()).thenReturn(true);
262         when(wifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED);
263 
264         final LongPressWifiEntryPreference connectedWifiEntryPreference =
265                 mWifiSettings2.createLongPressWifiEntryPreference(wifiEntry);
266         final View view = mock(View.class);
267         when(view.getTag()).thenReturn(connectedWifiEntryPreference);
268 
269         final ContextMenu menu = mock(ContextMenu.class);
270         mWifiSettings2.onCreateContextMenu(menu, view, null /* info */);
271 
272         verify(menu).add(anyInt(), eq(WifiSettings2.MENU_ID_FORGET), anyInt(), anyInt());
273         verify(menu).add(anyInt(), eq(WifiSettings2.MENU_ID_DISCONNECT), anyInt(), anyInt());
274     }
275 
276     @Test
onWifiEntriesChanged_shouldChangeNextButtonState()277     public void onWifiEntriesChanged_shouldChangeNextButtonState() {
278         mWifiSettings2.onWifiEntriesChanged();
279 
280         verify(mWifiSettings2).changeNextButtonState(anyBoolean());
281     }
282 
283     @Test
openSubscriptionHelpPage_shouldCallStartActivityForResult()284     public void openSubscriptionHelpPage_shouldCallStartActivityForResult() {
285         doReturn(new Intent()).when(mWifiSettings2).getHelpIntent(mContext, FAKE_URI_STRING);
286         doNothing().when(mWifiSettings2).startActivityForResult(any(Intent.class), anyInt());
287         final WifiEntry mockWifiEntry = mock(WifiEntry.class);
288         when(mockWifiEntry.getHelpUriString()).thenReturn(FAKE_URI_STRING);
289 
290         mWifiSettings2.openSubscriptionHelpPage(mockWifiEntry);
291 
292         verify(mWifiSettings2, times(1)).startActivityForResult(any(), anyInt());
293     }
294 
295     @Test
onNumSavedNetworksChanged_isFinishing_ShouldNotCrash()296     public void onNumSavedNetworksChanged_isFinishing_ShouldNotCrash() {
297         final FragmentActivity activity = mock(FragmentActivity.class);
298         when(activity.isFinishing()).thenReturn(true);
299         when(mWifiSettings2.getActivity()).thenReturn(activity);
300         when(mWifiSettings2.getContext()).thenReturn(null);
301 
302         mWifiSettings2.onNumSavedNetworksChanged();
303     }
304 
305     @Test
onNumSavedSubscriptionsChanged_isFinishing_ShouldNotCrash()306     public void onNumSavedSubscriptionsChanged_isFinishing_ShouldNotCrash() {
307         final FragmentActivity activity = mock(FragmentActivity.class);
308         when(activity.isFinishing()).thenReturn(true);
309         when(mWifiSettings2.getActivity()).thenReturn(activity);
310         when(mWifiSettings2.getContext()).thenReturn(null);
311 
312         mWifiSettings2.onNumSavedSubscriptionsChanged();
313     }
314 
315     @Test
onSubmit_modeModifyNoConfig_toastErrorMessage()316     public void onSubmit_modeModifyNoConfig_toastErrorMessage() {
317         WifiDialog2 dialog = createWifiDialog2(MODE_MODIFY, null /* config */);
318 
319         mWifiSettings2.onSubmit(dialog);
320 
321         assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
322                 mContext.getString(R.string.wifi_failed_save_message));
323     }
324 
325     @Test
onSubmit_modeModifyHasConfig_saveWifiManager()326     public void onSubmit_modeModifyHasConfig_saveWifiManager() {
327         final WifiConfiguration config = mock(WifiConfiguration.class);
328         WifiDialog2 dialog = createWifiDialog2(MODE_MODIFY, config);
329 
330         mWifiSettings2.onSubmit(dialog);
331 
332         verify(mWifiManager).save(eq(config), any());
333     }
334 
335     @Test
onSubmit_modeConnectNoConfig_connectWifiEntry()336     public void onSubmit_modeConnectNoConfig_connectWifiEntry() {
337         WifiDialog2 dialog = createWifiDialog2(MODE_CONNECT, null /* config */);
338         final WifiEntry wifiEntry = dialog.getWifiEntry();
339 
340         mWifiSettings2.onAttach(mContext);
341         mWifiSettings2.onSubmit(dialog);
342 
343         verify(mWifiSettings2).connect(wifiEntry, false /* editIfNoConfig */,
344                 false /* fullScreenEdit*/);
345     }
346 
347     @Test
onSubmit_modeConnectHasConfig_connectWifiManager()348     public void onSubmit_modeConnectHasConfig_connectWifiManager() {
349         final WifiConfiguration config = mock(WifiConfiguration.class);
350         WifiDialog2 dialog = createWifiDialog2(MODE_CONNECT, config);
351 
352         mWifiSettings2.onSubmit(dialog);
353 
354         verify(mWifiManager).connect(eq(config), any(WifiManager.ActionListener.class));
355     }
356 
createWifiDialog2(int mode, WifiConfiguration config)357     private WifiDialog2 createWifiDialog2(int mode, WifiConfiguration config) {
358         final WifiEntry wifiEntry = mock(WifiEntry.class);
359         when(wifiEntry.canConnect()).thenReturn(true);
360         final WifiConfigController2 controller = mock(WifiConfigController2.class);
361         when(controller.getConfig()).thenReturn(config);
362         final WifiDialog2 wifiDialog2 =  spy(WifiDialog2.createModal(mContext, null /* listener */,
363                 wifiEntry, mode));
364         when(wifiDialog2.getController()).thenReturn(controller);
365         return wifiDialog2;
366     }
367 }
368