From 2ff710a9119c6d003eb6e920d9ff8c857b55fc79 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Wed, 18 Jul 2018 17:01:53 -0700 Subject: [PATCH] Move logic from SavedAccessPoint fragment to controller Change-Id: Ic54e536f97490cec1746fa58c42ec55b60d17f0e Fixes: 64806699 Test: robotests --- .../utils/PreferenceGroupChildrenCache.java | 59 ++++++ src/com/android/settings/wifi/WifiDialog.java | 16 +- .../WifiDetailPreferenceController.java | 5 - ...SavedAccessPointsPreferenceController.java | 110 ++++++++++- .../SavedAccessPointsWifiSettings.java | 187 ++++-------------- .../testutils/shadow/ShadowAccessPoint.java | 31 +++ .../testutils/shadow/ShadowWifiManager.java | 11 +- .../android/settings/wifi/WifiDialogTest.java | 10 +- ...dAccessPointsPreferenceControllerTest.java | 135 +++++++++++++ .../SavedAccessPointsWifiSettingsTest.java | 83 ++++---- 10 files changed, 425 insertions(+), 222 deletions(-) create mode 100644 src/com/android/settings/utils/PreferenceGroupChildrenCache.java create mode 100644 tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessPoint.java create mode 100644 tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceControllerTest.java diff --git a/src/com/android/settings/utils/PreferenceGroupChildrenCache.java b/src/com/android/settings/utils/PreferenceGroupChildrenCache.java new file mode 100644 index 00000000000..dcbf4fdfe5c --- /dev/null +++ b/src/com/android/settings/utils/PreferenceGroupChildrenCache.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.utils; + +import android.text.TextUtils; +import android.util.ArrayMap; + +import androidx.preference.Preference; +import androidx.preference.PreferenceGroup; + +/** + * Class that helps track which {@link Preference}s in a {@link PreferenceGroup} are still being + * used, and remove unused ones. + */ +public class PreferenceGroupChildrenCache { + + private ArrayMap mPreferenceCache; + + public void cacheRemoveAllPrefs(PreferenceGroup group) { + mPreferenceCache = new ArrayMap<>(); + final int N = group.getPreferenceCount(); + for (int i = 0; i < N; i++) { + Preference p = group.getPreference(i); + if (TextUtils.isEmpty(p.getKey())) { + continue; + } + mPreferenceCache.put(p.getKey(), p); + } + } + + public void removeCachedPrefs(PreferenceGroup group) { + for (Preference p : mPreferenceCache.values()) { + group.removePreference(p); + } + mPreferenceCache = null; + } + + public Preference getCachedPreference(String key) { + return mPreferenceCache != null ? mPreferenceCache.remove(key) : null; + } + + public int getCachedCount() { + return mPreferenceCache != null ? mPreferenceCache.size() : 0; + } +} diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java index 79500e0b7ad..8c2739f28fe 100644 --- a/src/com/android/settings/wifi/WifiDialog.java +++ b/src/com/android/settings/wifi/WifiDialog.java @@ -27,11 +27,15 @@ import com.android.settings.R; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.wifi.AccessPoint; -public class WifiDialog extends AlertDialog implements WifiConfigUiBase, DialogInterface.OnClickListener { +public class WifiDialog extends AlertDialog implements WifiConfigUiBase, + DialogInterface.OnClickListener { public interface WifiDialogListener { - void onForget(WifiDialog dialog); - void onSubmit(WifiDialog dialog); + default void onForget(WifiDialog dialog) { + } + + default void onSubmit(WifiDialog dialog) { + } } private static final int BUTTON_SUBMIT = DialogInterface.BUTTON_POSITIVE; @@ -64,7 +68,7 @@ public class WifiDialog extends AlertDialog implements WifiConfigUiBase, DialogI } /* package */ WifiDialog(Context context, WifiDialogListener listener, AccessPoint accessPoint, - int mode, int style, boolean hideSubmitButton) { + int mode, int style, boolean hideSubmitButton) { super(context, style); mMode = mode; mListener = listener; @@ -99,8 +103,8 @@ public class WifiDialog extends AlertDialog implements WifiConfigUiBase, DialogI } public void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - mController.updatePassword(); + super.onRestoreInstanceState(savedInstanceState); + mController.updatePassword(); } @Override diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java index d291f9cb5a8..bda3b767cf3 100644 --- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java +++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java @@ -541,11 +541,6 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController mConnectivityManager.startCaptivePortalApp(mNetwork); } - @Override - public void onForget(WifiDialog dialog) { - // can't forget network from a 'modify' dialog - } - @Override public void onSubmit(WifiDialog dialog) { if (dialog.getController() != null) { diff --git a/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceController.java b/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceController.java index a7c40380419..dea44439b99 100644 --- a/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceController.java +++ b/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceController.java @@ -18,21 +18,127 @@ package com.android.settings.wifi.savedaccesspoints; import android.content.Context; +import android.net.wifi.WifiManager; +import android.util.Log; + +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; +import androidx.preference.PreferenceGroup; +import androidx.preference.PreferenceScreen; import com.android.settings.core.BasePreferenceController; +import com.android.settings.utils.PreferenceGroupChildrenCache; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnStart; +import com.android.settingslib.utils.ThreadUtils; +import com.android.settingslib.wifi.AccessPoint; +import com.android.settingslib.wifi.AccessPointPreference; +import com.android.settingslib.wifi.AccessPointPreference.UserBadgeCache; +import com.android.settingslib.wifi.WifiSavedConfigUtils; + +import java.util.Collections; +import java.util.List; /** - * Controller that manages a PrferenceGroup, which contains a list of saved access points. + * Controller that manages a PreferenceGroup, which contains a list of saved access points. */ -public class SavedAccessPointsPreferenceController extends BasePreferenceController { +public class SavedAccessPointsPreferenceController extends BasePreferenceController implements + LifecycleObserver, OnStart, Preference.OnPreferenceClickListener, + WifiManager.ActionListener { + + private static final String TAG = "SavedAPPrefCtrl"; + + private final WifiManager mWifiManager; + private final PreferenceGroupChildrenCache mChildrenCache; + + private final UserBadgeCache mUserBadgeCache; + private PreferenceGroup mPreferenceGroup; + private SavedAccessPointsWifiSettings mHost; public SavedAccessPointsPreferenceController(Context context, String preferenceKey) { super(context, preferenceKey); + mUserBadgeCache = new AccessPointPreference.UserBadgeCache(context.getPackageManager()); + mWifiManager = context.getSystemService(WifiManager.class); + mChildrenCache = new PreferenceGroupChildrenCache(); + } + + public SavedAccessPointsPreferenceController setHost(SavedAccessPointsWifiSettings host) { + mHost = host; + return this; } @Override public int getAvailabilityStatus() { return AVAILABLE; } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreferenceGroup = (PreferenceGroup) screen.findPreference(getPreferenceKey()); + } + + @Override + public void onStart() { + refreshSavedAccessPoints(); + } + + public void postRefreshSavedAccessPoints() { + ThreadUtils.postOnMainThread(() -> refreshSavedAccessPoints()); + } + + @Override + public boolean onPreferenceClick(Preference preference) { + if (mHost != null) { + mHost.showWifiDialog((AccessPointPreference) preference); + } + return false; + } + + @Override + public void onSuccess() { + postRefreshSavedAccessPoints(); + } + + @Override + public void onFailure(int reason) { + postRefreshSavedAccessPoints(); + } + + @VisibleForTesting + void refreshSavedAccessPoints() { + if (mPreferenceGroup == null) { + Log.w(TAG, "PreferenceGroup is null, skipping."); + return; + } + final Context prefContext = mPreferenceGroup.getContext(); + + final List accessPoints = + WifiSavedConfigUtils.getAllConfigs(mContext, mWifiManager); + Collections.sort(accessPoints, SavedNetworkComparator.INSTANCE); + mChildrenCache.cacheRemoveAllPrefs(mPreferenceGroup); + + final int accessPointsSize = accessPoints.size(); + for (int i = 0; i < accessPointsSize; ++i) { + AccessPoint ap = accessPoints.get(i); + String key = ap.getKey(); + AccessPointPreference preference = + (AccessPointPreference) mChildrenCache.getCachedPreference(key); + if (preference == null) { + preference = new AccessPointPreference(ap, prefContext, mUserBadgeCache, true); + preference.setKey(key); + preference.setIcon(null); + preference.setOnPreferenceClickListener(this); + mPreferenceGroup.addPreference(preference); + } + preference.setOrder(i); + } + + mChildrenCache.removeCachedPrefs(mPreferenceGroup); + + if (mPreferenceGroup.getPreferenceCount() < 1) { + Log.w(TAG, "Saved networks activity loaded, but there are no saved networks!"); + } + } } diff --git a/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java b/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java index 930cd854331..8f14ec21d70 100644 --- a/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java +++ b/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettings.java @@ -17,18 +17,12 @@ package com.android.settings.wifi.savedaccesspoints; import android.annotation.Nullable; -import android.app.Activity; import android.app.Dialog; import android.content.Context; +import android.content.DialogInterface; import android.net.wifi.WifiManager; import android.os.Bundle; -import android.os.Handler; import android.util.Log; -import android.widget.Toast; - -import androidx.annotation.VisibleForTesting; -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -39,68 +33,19 @@ import com.android.settings.wifi.WifiDialog; import com.android.settings.wifi.WifiSettings; import com.android.settingslib.wifi.AccessPoint; import com.android.settingslib.wifi.AccessPointPreference; -import com.android.settingslib.wifi.WifiSavedConfigUtils; - -import java.util.Collections; -import java.util.List; /** * UI to manage saved networks/access points. */ public class SavedAccessPointsWifiSettings extends DashboardFragment - implements WifiDialog.WifiDialogListener { + implements WifiDialog.WifiDialogListener, DialogInterface.OnCancelListener { + private static final String TAG = "SavedAccessPoints"; - @VisibleForTesting - static final int MSG_UPDATE_PREFERENCES = 1; - @VisibleForTesting - final WifiManager.ActionListener mForgetListener = new WifiManager.ActionListener() { - @Override - public void onSuccess() { - postUpdatePreference(); - } - - @Override - public void onFailure(int reason) { - postUpdatePreference(); - } - }; - - @VisibleForTesting - final Handler mHandler = new Handler() { - @Override - public void handleMessage(android.os.Message msg) { - if (msg.what == MSG_UPDATE_PREFERENCES) { - initPreferences(); - } - } - }; - - private final WifiManager.ActionListener mSaveListener = new WifiManager.ActionListener() { - @Override - public void onSuccess() { - postUpdatePreference(); - } - - @Override - public void onFailure(int reason) { - Activity activity = getActivity(); - if (activity != null) { - Toast.makeText(activity, - R.string.wifi_failed_save_message, - Toast.LENGTH_SHORT).show(); - } - } - }; - - private WifiDialog mDialog; private WifiManager mWifiManager; - private AccessPoint mDlgAccessPoint; private Bundle mAccessPointSavedState; private AccessPoint mSelectedAccessPoint; - private AccessPointPreference.UserBadgeCache mUserBadgeCache; - // Instance state key private static final String SAVE_DIALOG_ACCESS_POINT_STATE = "wifi_ap_state"; @@ -122,21 +67,15 @@ public class SavedAccessPointsWifiSettings extends DashboardFragment @Override public void onAttach(Context context) { super.onAttach(context); - mUserBadgeCache = new AccessPointPreference.UserBadgeCache(getPackageManager()); - } - - @Override - public void onResume() { - super.onResume(); - initPreferences(); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); mWifiManager = (WifiManager) getContext() .getApplicationContext().getSystemService(Context.WIFI_SERVICE); + use(SavedAccessPointsPreferenceController.class) + .setHost(this); + } + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); if (savedInstanceState != null) { if (savedInstanceState.containsKey(SAVE_DIALOG_ACCESS_POINT_STATE)) { mAccessPointSavedState = @@ -145,55 +84,15 @@ public class SavedAccessPointsWifiSettings extends DashboardFragment } } - private void initPreferences() { - PreferenceScreen preferenceScreen = getPreferenceScreen(); - final Context context = getPrefContext(); - - final List accessPoints = - WifiSavedConfigUtils.getAllConfigs(context, mWifiManager); - Collections.sort(accessPoints, SavedNetworkComparator.INSTANCE); - cacheRemoveAllPrefs(preferenceScreen); - - final int accessPointsSize = accessPoints.size(); - for (int i = 0; i < accessPointsSize; ++i) { - AccessPoint ap = accessPoints.get(i); - String key = ap.getKey(); - AccessPointPreference preference = - (AccessPointPreference) getCachedPreference(key); - if (preference == null) { - preference = new AccessPointPreference(ap, context, mUserBadgeCache, true); - preference.setKey(key); - preference.setIcon(null); - preferenceScreen.addPreference(preference); - } - preference.setOrder(i); - } - - removeCachedPrefs(preferenceScreen); - - if (getPreferenceScreen().getPreferenceCount() < 1) { - Log.w(TAG, "Saved networks activity loaded, but there are no saved networks!"); - } - } - - private void postUpdatePreference() { - if (!mHandler.hasMessages(MSG_UPDATE_PREFERENCES)) { - mHandler.sendEmptyMessage(MSG_UPDATE_PREFERENCES); - } - } - - private void showWifiDialog(@Nullable AccessPointPreference accessPoint) { - if (mDialog != null) { - removeDialog(WifiSettings.WIFI_DIALOG_ID); - mDialog = null; - } + public void showWifiDialog(@Nullable AccessPointPreference accessPoint) { + removeDialog(WifiSettings.WIFI_DIALOG_ID); if (accessPoint != null) { // Save the access point and edit mode - mDlgAccessPoint = accessPoint.getAccessPoint(); + mSelectedAccessPoint = accessPoint.getAccessPoint(); } else { // No access point is selected. Clear saved state. - mDlgAccessPoint = null; + mSelectedAccessPoint = null; mAccessPointSavedState = null; } @@ -204,24 +103,18 @@ public class SavedAccessPointsWifiSettings extends DashboardFragment public Dialog onCreateDialog(int dialogId) { switch (dialogId) { case WifiSettings.WIFI_DIALOG_ID: - if (mDlgAccessPoint == null && mAccessPointSavedState == null) { - // Add new network - mDialog = WifiDialog.createFullscreen(getActivity(), this, null, - WifiConfigUiBase.MODE_CONNECT); - } else { - // Modify network - if (mDlgAccessPoint == null) { - // Restore AP from save state - mDlgAccessPoint = new AccessPoint(getActivity(), mAccessPointSavedState); - // Reset the saved access point data - mAccessPointSavedState = null; - } - mDialog = WifiDialog.createModal(getActivity(), this, mDlgAccessPoint, - WifiConfigUiBase.MODE_VIEW); + // Modify network + if (mSelectedAccessPoint == null) { + // Restore AP from save state + mSelectedAccessPoint = new AccessPoint(getActivity(), mAccessPointSavedState); + // Reset the saved access point data + mAccessPointSavedState = null; } - mSelectedAccessPoint = mDlgAccessPoint; + final WifiDialog dialog = WifiDialog.createModal( + getActivity(), this, mSelectedAccessPoint, WifiConfigUiBase.MODE_VIEW); + dialog.setOnCancelListener(this); - return mDialog; + return dialog; } return super.onCreateDialog(dialogId); } @@ -239,14 +132,12 @@ public class SavedAccessPointsWifiSettings extends DashboardFragment @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); - - // If the dialog is showing, save its state. - if (mDialog != null && mDialog.isShowing()) { - if (mDlgAccessPoint != null) { - mAccessPointSavedState = new Bundle(); - mDlgAccessPoint.saveWifiState(mAccessPointSavedState); - outState.putBundle(SAVE_DIALOG_ACCESS_POINT_STATE, mAccessPointSavedState); - } + // If the dialog is showing (indicated by the existence of mSelectedAccessPoint), then we + // save its state. + if (mSelectedAccessPoint != null) { + mAccessPointSavedState = new Bundle(); + mSelectedAccessPoint.saveWifiState(mAccessPointSavedState); + outState.putBundle(SAVE_DIALOG_ACCESS_POINT_STATE, mAccessPointSavedState); } } @@ -261,27 +152,19 @@ public class SavedAccessPointsWifiSettings extends DashboardFragment Log.e(TAG, "Failed to remove Passpoint configuration for " + mSelectedAccessPoint.getConfigName()); } - postUpdatePreference(); + use(SavedAccessPointsPreferenceController.class) + .postRefreshSavedAccessPoints(); } else { // mForgetListener will call initPreferences upon completion - mWifiManager.forget(mSelectedAccessPoint.getConfig().networkId, mForgetListener); + mWifiManager.forget(mSelectedAccessPoint.getConfig().networkId, + use(SavedAccessPointsPreferenceController.class)); } mSelectedAccessPoint = null; } } @Override - public void onSubmit(WifiDialog dialog) { - mWifiManager.save(dialog.getController().getConfig(), mSaveListener); - } - - @Override - public boolean onPreferenceTreeClick(Preference preference) { - if (preference instanceof AccessPointPreference) { - showWifiDialog((AccessPointPreference) preference); - return true; - } else { - return super.onPreferenceTreeClick(preference); - } + public void onCancel(DialogInterface dialog) { + mSelectedAccessPoint = null; } } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessPoint.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessPoint.java new file mode 100644 index 00000000000..2cb6964b779 --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessPoint.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.testutils.shadow; + +import com.android.settingslib.wifi.AccessPoint; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +@Implements(AccessPoint.class) +public class ShadowAccessPoint { + + @Implementation + public String getSavedNetworkSummary() { + return "saved"; + } +} diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowWifiManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowWifiManager.java index e5304daf1bf..65f92a32727 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowWifiManager.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowWifiManager.java @@ -20,13 +20,17 @@ import static org.robolectric.RuntimeEnvironment.application; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; +import android.net.wifi.hotspot2.PasspointConfiguration; import org.robolectric.annotation.HiddenApi; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.shadow.api.Shadow; -@Implements(WifiManager.class) +import java.util.Collections; +import java.util.List; + +@Implements(value = WifiManager.class, inheritImplementationMethods = true) public class ShadowWifiManager extends org.robolectric.shadows.ShadowWifiManager { public WifiConfiguration savedWifiConfig; @@ -43,6 +47,11 @@ public class ShadowWifiManager extends org.robolectric.shadows.ShadowWifiManager savedWifiConfig = config; } + @Implementation + public List getPasspointConfigurations() { + return Collections.emptyList(); + } + public static ShadowWifiManager get() { return Shadow.extract(application.getSystemService(WifiManager.class)); } diff --git a/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java b/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java index 7025100a99e..7a88131df89 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiDialogTest.java @@ -25,15 +25,7 @@ public class WifiDialogTest { private Context mContext = RuntimeEnvironment.application; - private WifiDialogListener mListener = new WifiDialogListener() { - @Override - public void onForget(WifiDialog dialog) { - } - - @Override - public void onSubmit(WifiDialog dialog) { - } - }; + private WifiDialogListener mListener = new WifiDialogListener() {}; @Before public void setUp() { diff --git a/tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceControllerTest.java new file mode 100644 index 00000000000..790739aec8b --- /dev/null +++ b/tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsPreferenceControllerTest.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.wifi.savedaccesspoints; + +import static com.android.settings.core.BasePreferenceController.AVAILABLE; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.net.wifi.WifiConfiguration; + +import androidx.preference.PreferenceCategory; +import androidx.preference.PreferenceScreen; + +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.shadow.ShadowAccessPoint; +import com.android.settings.testutils.shadow.ShadowThreadUtils; +import com.android.settings.testutils.shadow.ShadowWifiManager; +import com.android.settingslib.wifi.AccessPointPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(shadows = {ShadowThreadUtils.class, ShadowWifiManager.class}) +public class SavedAccessPointsPreferenceControllerTest { + + @Mock + private PreferenceScreen mPreferenceScreen; + @Mock + private PreferenceCategory mPreferenceCategory; + + private Context mContext; + private ShadowWifiManager mWifiManager; + private SavedAccessPointsPreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mWifiManager = ShadowWifiManager.get(); + mController = spy(new SavedAccessPointsPreferenceController(mContext, "test_key")); + + when(mPreferenceScreen.findPreference(mController.getPreferenceKey())) + .thenReturn(mPreferenceCategory); + when(mPreferenceCategory.getContext()).thenReturn(mContext); + } + + @Test + public void getAvailability_alwaysAvailable() { + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } + + @Test + public void onStart_shouldRefreshApList() { + doNothing().when(mController).refreshSavedAccessPoints(); + + mController.onStart(); + + verify(mController).refreshSavedAccessPoints(); + } + + + @Test + public void postRefresh_shouldRefreshApList() { + doNothing().when(mController).refreshSavedAccessPoints(); + + mController.postRefreshSavedAccessPoints(); + + verify(mController).refreshSavedAccessPoints(); + } + + @Test + public void forget_onSuccess_shouldRefreshApList() { + doNothing().when(mController).refreshSavedAccessPoints(); + + mController.onSuccess(); + + verify(mController).refreshSavedAccessPoints(); + } + + @Test + public void forget_onFailure_shouldRefreshApList() { + doNothing().when(mController).refreshSavedAccessPoints(); + + mController.onFailure(0 /* reason */); + + verify(mController).refreshSavedAccessPoints(); + } + + @Test + @Config(shadows = ShadowAccessPoint.class) + public void refreshSavedAccessPoints_shouldListAllAPs() { + final WifiConfiguration config = new WifiConfiguration(); + config.SSID = "SSID"; + config.BSSID = "BSSID"; + config.networkId = 2; + mWifiManager.addNetwork(config); + + final ArgumentCaptor captor = + ArgumentCaptor.forClass(AccessPointPreference.class); + mController.displayPreference(mPreferenceScreen); + mController.refreshSavedAccessPoints(); + + verify(mPreferenceCategory).addPreference(captor.capture()); + + final AccessPointPreference pref = captor.getValue(); + assertThat(pref.getTitle()).isEqualTo(config.SSID); + } +} diff --git a/tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettingsTest.java index a98839027f2..97ad7d9b2f3 100644 --- a/tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettingsTest.java +++ b/tests/robotests/src/com/android/settings/wifi/savedaccesspoints/SavedAccessPointsWifiSettingsTest.java @@ -18,22 +18,20 @@ package com.android.settings.wifi.savedaccesspoints; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.ActionListener; -import android.os.Handler; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.wifi.WifiConfigController; import com.android.settings.wifi.WifiDialog; +import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.wifi.AccessPoint; import org.junit.Before; @@ -47,69 +45,53 @@ import org.robolectric.util.ReflectionHelpers; public class SavedAccessPointsWifiSettingsTest { @Mock - private WifiManager mockWifiManager; + private WifiManager mWifiManager; @Mock - private WifiDialog mockWifiDialog; + private WifiDialog mWifiDialog; @Mock - private WifiConfigController mockConfigController; + private WifiConfigController mConfigController; @Mock - private WifiConfiguration mockWifiConfiguration; + private WifiConfiguration mWifiConfiguration; @Mock - private AccessPoint mockAccessPoint; + private AccessPoint mAccessPoint; @Mock - private Handler mHandler; + private SavedAccessPointsPreferenceController mSavedApController; - private SavedAccessPointsWifiSettings mSettings; + private TestFragment mSettings; @Before public void setUp() { MockitoAnnotations.initMocks(this); - mSettings = new SavedAccessPointsWifiSettings(); - ReflectionHelpers.setField(mSettings, "mHandler", mHandler); - ReflectionHelpers.setField(mSettings, "mWifiManager", mockWifiManager); + mSettings = spy(new TestFragment()); - when(mockWifiDialog.getController()).thenReturn(mockConfigController); - when(mockConfigController.getConfig()).thenReturn(mockWifiConfiguration); + doReturn(mSavedApController).when(mSettings) + .use(SavedAccessPointsPreferenceController.class); + + ReflectionHelpers.setField(mSettings, "mWifiManager", mWifiManager); + + when(mWifiDialog.getController()).thenReturn(mConfigController); + when(mConfigController.getConfig()).thenReturn(mWifiConfiguration); } @Test - public void onForget_isPasspointConfig_shouldSendMessageToHandler() { - final AccessPoint accessPoint = mock(AccessPoint.class); - when(accessPoint.isPasspointConfig()).thenReturn(true); - ReflectionHelpers.setField(mSettings, "mSelectedAccessPoint", accessPoint); + public void onForget_isPasspointConfig_shouldRefreshAPList() { + when(mAccessPoint.isPasspointConfig()).thenReturn(true); + ReflectionHelpers.setField(mSettings, "mSelectedAccessPoint", mAccessPoint); mSettings.onForget(null); - verify(mHandler).sendEmptyMessage(SavedAccessPointsWifiSettings.MSG_UPDATE_PREFERENCES); - } - - @Test - public void onForget_onSuccess_shouldSendMessageToHandler() { - mSettings.mForgetListener.onSuccess(); - - verify(mHandler).sendEmptyMessage(SavedAccessPointsWifiSettings.MSG_UPDATE_PREFERENCES); - } - - @Test - public void onForget_onFailure_shouldSendMessageToHandler() { - mSettings.mForgetListener.onFailure(0); - - verify(mHandler).sendEmptyMessage(SavedAccessPointsWifiSettings.MSG_UPDATE_PREFERENCES); - } - - @Test - public void onSubmit_shouldInvokeSaveApi() { - mSettings.onSubmit(mockWifiDialog); - verify(mockWifiManager).save(eq(mockWifiConfiguration), any(ActionListener.class)); + verify(mSavedApController).postRefreshSavedAccessPoints(); } @Test public void onForget_shouldInvokeForgetApi() { - ReflectionHelpers.setField(mSettings, "mSelectedAccessPoint", mockAccessPoint); - when(mockAccessPoint.getConfig()).thenReturn(mockWifiConfiguration); - mSettings.onForget(mockWifiDialog); - verify(mockWifiManager) - .forget(eq(mockWifiConfiguration.networkId), any(ActionListener.class)); + ReflectionHelpers.setField(mSettings, "mSelectedAccessPoint", mAccessPoint); + when(mAccessPoint.getConfig()).thenReturn(mWifiConfiguration); + + mSettings.onForget(mWifiDialog); + + verify(mWifiManager) + .forget(mWifiConfiguration.networkId, mSavedApController); } @Test @@ -118,4 +100,11 @@ public class SavedAccessPointsWifiSettingsTest { assertThat(mSettings.getPreferenceScreenResId()) .isEqualTo(R.xml.wifi_display_saved_access_points); } + + public static class TestFragment extends SavedAccessPointsWifiSettings { + + public T use(Class clazz) { + return super.use(clazz); + } + } }