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: I567b2b80163631a01d165c0ac5c0aba392e014ef
This commit is contained in:
Weng Su
2020-10-20 15:38:11 +08:00
parent 886fe1e6ab
commit 3a45d054eb
4 changed files with 82 additions and 6 deletions

View File

@@ -36,6 +36,7 @@ import android.view.Menu;
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 @@ public class WifiNetworkDetailsFragment2 extends DashboardFragment implements
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 @@ public class WifiNetworkDetailsFragment2 extends DashboardFragment implements
* 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,

View File

@@ -69,12 +69,13 @@ public class WifiPrivacyPreferenceController2 extends BasePreferenceController i
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);
}
}

View File

@@ -24,6 +24,7 @@ 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;
@@ -32,14 +33,25 @@ 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
@@ -73,4 +85,44 @@ public class WifiNetworkDetailsFragment2Test {
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;
}
}
}

View File

@@ -89,7 +89,15 @@ public class WifiPrivacyPreferenceController2Test {
}
@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 @@ public class WifiPrivacyPreferenceController2Test {
}
@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);