Fix the Wi-Fi detailed settings un-editable issue.
- The WifiEntry info might not be ready in early stage. (ex:
WifiEntry#canSetPrivacy())
- The Wi-Fi detailed setting listens to the WifiEntry callback to
refresh the preferences, it should first update the preference status to
be editable or not, and then display preferences to the UI.
- The privicy preference should be able to set back to selectable when
WifiEntry#canSetPrivicy() change from false to true.
Bug: 170148009
Test:
make RunSettingsRoboTests
ROBOTEST_FILTER=WifiNetworkDetailsFragment2Test
make RunSettingsRoboTests
ROBOTEST_FILTER=WifiPrivacyPreferenceController2Test
Change-Id: I48ca060e6b468232f19c82e9de0ce4fce39cba7f
Merged-In: I567b2b80163631a01d165c0ac5c0aba392e014ef
diff --git a/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java b/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
index 76a8c5f..d0708ea 100644
--- a/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
+++ b/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2.java
@@ -36,6 +36,7 @@
import android.view.MenuInflater;
import android.view.MenuItem;
+import androidx.annotation.VisibleForTesting;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
@@ -78,7 +79,8 @@
private HandlerThread mWorkerThread;
private WifiDetailPreferenceController2 mWifiDetailPreferenceController2;
private List<WifiDialog2.WifiDialog2Listener> mWifiDialogListeners = new ArrayList<>();
- private List<AbstractPreferenceController> mControllers;
+ @VisibleForTesting
+ List<AbstractPreferenceController> mControllers;
@Override
public void onDestroy() {
@@ -255,6 +257,11 @@
* API call for refreshing the preferences in this fragment.
*/
public void refreshPreferences() {
+ updatePreferenceStates();
+ displayPreferenceControllers();
+ }
+
+ protected void displayPreferenceControllers() {
final PreferenceScreen screen = getPreferenceScreen();
for (AbstractPreferenceController controller : mControllers) {
// WifiDetailPreferenceController2 gets the callback WifiEntryCallback#onUpdated,
diff --git a/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2.java b/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2.java
index a0d4b16..d6e1b60 100644
--- a/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2.java
+++ b/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2.java
@@ -69,12 +69,13 @@
public void updateState(Preference preference) {
final DropDownPreference dropDownPreference = (DropDownPreference) preference;
final int randomizationLevel = getRandomizationValue();
+ final boolean isSelectable = mWifiEntry.canSetPrivacy();
+ preference.setSelectable(isSelectable);
dropDownPreference.setValue(Integer.toString(randomizationLevel));
updateSummary(dropDownPreference, randomizationLevel);
- // Makes preference not selectable, when this is a ephemeral network.
- if (!mWifiEntry.canSetPrivacy()) {
- preference.setSelectable(false);
+ // If the preference cannot be selectable, display a temporary network in the summary.
+ if (!isSelectable) {
dropDownPreference.setSummary(R.string.wifi_privacy_settings_ephemeral_summary);
}
}
diff --git a/tests/robotests/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2Test.java b/tests/robotests/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2Test.java
new file mode 100644
index 0000000..e0fb578
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/details2/WifiNetworkDetailsFragment2Test.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2020 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.details2;
+
+import static com.android.settings.wifi.WifiSettings.WIFI_DIALOG_ID;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.settings.SettingsEnums;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.ArrayList;
+
+@RunWith(RobolectricTestRunner.class)
+public class WifiNetworkDetailsFragment2Test {
+
+ final String TEST_PREFERENCE_KEY = "TEST_PREFERENCE_KEY";
+
+ private WifiNetworkDetailsFragment2 mFragment;
+
+ @Before
+ public void setUp() {
+ mFragment = new WifiNetworkDetailsFragment2();
+ }
+
+ @Test
+ public void getMetricsCategory_shouldReturnWifiNetworkDetails() {
+ assertThat(mFragment.getMetricsCategory()).isEqualTo(SettingsEnums.WIFI_NETWORK_DETAILS);
+ }
+
+ @Test
+ public void getDialogMetricsCategory_withCorrectId_shouldReturnDialogWifiApEdit() {
+ assertThat(mFragment.getDialogMetricsCategory(WIFI_DIALOG_ID)).isEqualTo(
+ SettingsEnums.DIALOG_WIFI_AP_EDIT);
+ }
+
+ @Test
+ public void getDialogMetricsCategory_withWrongId_shouldReturnZero() {
+ assertThat(mFragment.getDialogMetricsCategory(-1 /* dialogId */)).isEqualTo(0);
+ }
+
+ @Test
+ public void onCreateOptionsMenu_shouldSetCorrectIcon() {
+ final Menu menu = mock(Menu.class);
+ final MenuItem menuItem = mock(MenuItem.class);
+ doReturn(menuItem).when(menu).add(anyInt(), eq(Menu.FIRST), anyInt(), anyInt());
+
+ mFragment.onCreateOptionsMenu(menu, mock(MenuInflater.class));
+
+ verify(menuItem).setIcon(com.android.internal.R.drawable.ic_mode_edit);
+ }
+
+ @Test
+ public void refreshPreferences_controllerShouldUpdateStateAndDisplayPreference() {
+ final FakeFragment fragment = spy(new FakeFragment());
+ final PreferenceScreen screen = mock(PreferenceScreen.class);
+ final Preference preference = mock(Preference.class);
+ final TestController controller = mock(TestController.class);
+ doReturn(screen).when(fragment).getPreferenceScreen();
+ doReturn(preference).when(screen).findPreference(TEST_PREFERENCE_KEY);
+ doReturn(TEST_PREFERENCE_KEY).when(controller).getPreferenceKey();
+ fragment.mControllers = new ArrayList<>();
+ fragment.mControllers.add(controller);
+ fragment.addPreferenceController(controller);
+
+ fragment.refreshPreferences();
+
+ verify(controller).updateState(preference);
+ verify(controller).displayPreference(screen);
+ }
+
+ // Fake WifiNetworkDetailsFragment2 to override the protected method as public.
+ public class FakeFragment extends WifiNetworkDetailsFragment2 {
+
+ @Override
+ public void addPreferenceController(AbstractPreferenceController controller) {
+ super.addPreferenceController(controller);
+ }
+ }
+
+ public class TestController extends BasePreferenceController {
+
+ public TestController() {
+ super(RuntimeEnvironment.application, TEST_PREFERENCE_KEY);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2Test.java b/tests/robotests/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2Test.java
index 0414b1c..d3244fa 100644
--- a/tests/robotests/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2Test.java
+++ b/tests/robotests/src/com/android/settings/wifi/details2/WifiPrivacyPreferenceController2Test.java
@@ -89,7 +89,15 @@
}
@Test
- public void testUpdateState_canSetPrivacy_shouldBeSelectable() {
+ public void testUpdateState_canSetPrivacyInNextUpdate_shouldBeSelectable() {
+ // Return false in WifiEntry#canSetPrivacy to make preference un-selectable first.
+ when(mMockWifiEntry.canSetPrivacy()).thenReturn(false);
+
+ mPreferenceController.updateState(mDropDownPreference);
+
+ assertThat(mDropDownPreference.isSelectable()).isFalse();
+
+ // Return true in WifiEntry#canSetPrivacy to verify preference back to selectable.
when(mMockWifiEntry.canSetPrivacy()).thenReturn(true);
mPreferenceController.updateState(mDropDownPreference);
@@ -98,7 +106,15 @@
}
@Test
- public void testUpdateState_canNotSetPrivacy_shouldNotSelectable() {
+ public void testUpdateState_canNotSetPrivacyInNextUpdate_shouldNotBeSelectable() {
+ // Return true in WifiEntry#canSetPrivacy to make preference selectable first.
+ when(mMockWifiEntry.canSetPrivacy()).thenReturn(true);
+
+ mPreferenceController.updateState(mDropDownPreference);
+
+ assertThat(mDropDownPreference.isSelectable()).isTrue();
+
+ // Return false in WifiEntry#canSetPrivacy to verify preference back to un-selectable.
when(mMockWifiEntry.canSetPrivacy()).thenReturn(false);
mPreferenceController.updateState(mDropDownPreference);