Merge "Fix settings flakiness bug" into main
diff --git a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
index 2f04b62..4fc0e16 100644
--- a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
+++ b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java
@@ -46,6 +46,7 @@
import android.service.autofill.AutofillServiceInfo;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import android.view.View;
import android.widget.CompoundButton;
@@ -77,6 +78,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Executor;
@@ -114,7 +116,7 @@
private @Nullable String mFlagOverrideForTest = null;
private @Nullable PreferenceScreen mPreferenceScreen = null;
- private boolean mVisibility = false;
+ private Optional<Boolean> mSimulateHiddenForTests = Optional.empty();
private boolean mIsWorkProfile = false;
private boolean mSimulateConnectedForTests = false;
@@ -159,7 +161,9 @@
return UNSUPPORTED_ON_DEVICE;
}
- if (!mVisibility) {
+ // If there is no top provider or any providers in the list then
+ // we should hide this pref.
+ if (isHiddenDueToNoProviderSet()) {
return CONDITIONALLY_UNAVAILABLE;
}
@@ -378,20 +382,29 @@
}
@VisibleForTesting
- public void setVisibility(boolean newVisibility) {
- if (newVisibility == mVisibility) {
- return;
- }
-
- mVisibility = newVisibility;
+ public void forceDelegateRefresh() {
if (mDelegate != null) {
mDelegate.forceDelegateRefresh();
}
}
@VisibleForTesting
- public boolean getVisibility() {
- return mVisibility;
+ public void setSimulateHiddenForTests(Optional<Boolean> simulateHiddenForTests) {
+ mSimulateHiddenForTests = simulateHiddenForTests;
+ }
+
+ @VisibleForTesting
+ public boolean isHiddenDueToNoProviderSet() {
+ return isHiddenDueToNoProviderSet(getProviders());
+ }
+
+ private boolean isHiddenDueToNoProviderSet(
+ Pair<List<CombinedProviderInfo>, CombinedProviderInfo> providerPair) {
+ if (mSimulateHiddenForTests.isPresent()) {
+ return mSimulateHiddenForTests.get();
+ }
+
+ return (providerPair.first.size() == 0 || providerPair.second == null);
}
@VisibleForTesting
@@ -459,10 +472,11 @@
return preference;
}
- /** Aggregates the list of services and builds a list of UI prefs to show. */
- @VisibleForTesting
- public Map<String, CombiPreference> buildPreferenceList(
- Context context, PreferenceGroup group) {
+ /**
+ * Returns a pair that contains a list of the providers in the first position and the top
+ * provider in the second position.
+ */
+ private Pair<List<CombinedProviderInfo>, CombinedProviderInfo> getProviders() {
// Get the selected autofill provider. If it is the placeholder then replace it with an
// empty string.
String selectedAutofillProvider =
@@ -475,15 +489,25 @@
// Get the list of combined providers.
List<CombinedProviderInfo> providers =
CombinedProviderInfo.buildMergedList(
- AutofillServiceInfo.getAvailableServices(context, getUser()),
+ AutofillServiceInfo.getAvailableServices(mContext, getUser()),
mServices,
selectedAutofillProvider);
+ return new Pair<>(providers, CombinedProviderInfo.getTopProvider(providers));
+ }
- // Get the provider that is displayed at the top. If there is none then hide
- // everything.
- CombinedProviderInfo topProvider = CombinedProviderInfo.getTopProvider(providers);
- if (topProvider == null) {
- setVisibility(false);
+ /** Aggregates the list of services and builds a list of UI prefs to show. */
+ @VisibleForTesting
+ public @NonNull Map<String, CombiPreference> buildPreferenceList(
+ @NonNull Context context, @NonNull PreferenceGroup group) {
+ // Get the providers and extract the values.
+ Pair<List<CombinedProviderInfo>, CombinedProviderInfo> providerPair = getProviders();
+ CombinedProviderInfo topProvider = providerPair.second;
+ List<CombinedProviderInfo> providers = providerPair.first;
+
+ // If the provider is set to "none" or there are no providers then we should not
+ // return any providers.
+ if (isHiddenDueToNoProviderSet(providerPair)) {
+ forceDelegateRefresh();
return new HashMap<>();
}
@@ -520,7 +544,7 @@
}
// Set the visibility if we have services.
- setVisibility(!output.isEmpty());
+ forceDelegateRefresh();
return output;
}
diff --git a/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
index acf590b..b5aeac7 100644
--- a/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java
@@ -17,6 +17,7 @@
package com.android.settings.applications.credentials;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
@@ -55,6 +56,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
@RunWith(AndroidJUnit4.class)
@@ -121,17 +123,34 @@
createControllerWithServices(Lists.newArrayList(createCredentialProviderInfo()));
controller.setSimulateConnectedForTests(true);
assertThat(controller.isConnected()).isTrue();
- controller.setVisibility(true);
- assertThat(controller.getVisibility()).isTrue();
+ controller.setSimulateHiddenForTests(Optional.of(false));
+ assertThat(controller.isHiddenDueToNoProviderSet()).isFalse();
assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
+ public void getAvailabilityStatus_isHidden_returnsConditionallyUnavailable() {
+ CredentialManagerPreferenceController controller =
+ createControllerWithServices(Lists.newArrayList(createCredentialProviderInfo()));
+ controller.setSimulateConnectedForTests(true);
+ assertThat(controller.isConnected()).isTrue();
+ controller.setSimulateHiddenForTests(Optional.of(true));
+ assertThat(controller.isHiddenDueToNoProviderSet()).isTrue();
+ assertThat(controller.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+ }
+
+ @Test
public void displayPreference_withServices_preferencesAdded() {
CredentialManagerPreferenceController controller =
createControllerWithServices(Lists.newArrayList(createCredentialProviderInfo()));
+ controller.setSimulateConnectedForTests(true);
+ controller.setSimulateHiddenForTests(Optional.of(false));
+
+ assertThat(controller.isHiddenDueToNoProviderSet()).isFalse();
+ assertThat(controller.isConnected()).isTrue();
+ assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+
controller.displayPreference(mScreen);
- assertThat(controller.isConnected()).isFalse();
assertThat(mCredentialsPreferenceCategory.getPreferenceCount()).isEqualTo(1);
Preference pref = mCredentialsPreferenceCategory.getPreference(0);
@@ -150,8 +169,8 @@
createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2));
controller.setSimulateConnectedForTests(true);
assertThat(controller.isConnected()).isTrue();
- controller.setVisibility(true);
- assertThat(controller.getVisibility()).isTrue();
+ controller.setSimulateHiddenForTests(Optional.of(false));
+ assertThat(controller.isHiddenDueToNoProviderSet()).isFalse();
assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
// Test the data is correct.
@@ -194,8 +213,8 @@
createCredentialProviderInfo("com.android.provider6", "ClassA")));
controller.setSimulateConnectedForTests(true);
assertThat(controller.isConnected()).isTrue();
- controller.setVisibility(true);
- assertThat(controller.getVisibility()).isTrue();
+ controller.setSimulateHiddenForTests(Optional.of(false));
+ assertThat(controller.isHiddenDueToNoProviderSet()).isFalse();
assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
// Ensure that we stay under 5 providers.
@@ -263,8 +282,8 @@
createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2));
controller.setSimulateConnectedForTests(true);
assertThat(controller.isConnected()).isTrue();
- controller.setVisibility(true);
- assertThat(controller.getVisibility()).isTrue();
+ controller.setSimulateHiddenForTests(Optional.of(false));
+ assertThat(controller.isHiddenDueToNoProviderSet()).isFalse();
assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
// Test the data is correct.
@@ -316,9 +335,14 @@
CredentialManagerPreferenceController controller =
createControllerWithServices(
Lists.newArrayList(serviceA1, serviceB1, serviceC1, serviceC2, serviceC3));
- controller.displayPreference(mScreen);
+ controller.setSimulateConnectedForTests(true);
+ controller.setSimulateHiddenForTests(Optional.of(false));
- assertThat(controller.isConnected()).isFalse();
+ assertThat(controller.isHiddenDueToNoProviderSet()).isFalse();
+ assertThat(controller.isConnected()).isTrue();
+ assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+
+ controller.displayPreference(mScreen);
assertThat(mCredentialsPreferenceCategory.getPreferenceCount()).isEqualTo(3);
Map<String, CredentialManagerPreferenceController.CombiPreference> prefs =