From e174f66a71d4efddfce53646a9daf908412a314c Mon Sep 17 00:00:00 2001 From: Becca Hughes Date: Mon, 6 Mar 2023 18:59:15 +0000 Subject: [PATCH] Move CredentialProviderInfo for test/settings (settings) This is a precusor CL to adding a subtitle for settings to use so we need to move CPI where it can be used by settings, atest and CTS. Test: ondevice & atest & cts Bug: 253157366 Change-Id: Ief25f562eb5c2ca4438701de8a8e26941a8370a3 (cherry picked from commit on googleplex-android-review.googlesource.com host: 573e844275e3bc9da2de83cb419562172518ebb6) Merged-In: Ief25f562eb5c2ca4438701de8a8e26941a8370a3 --- ...CredentialManagerPreferenceController.java | 77 +++++-------- ...entialManagerPreferenceControllerTest.java | 104 +++++++++++++++--- 2 files changed, 116 insertions(+), 65 deletions(-) diff --git a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java index 0bccfe2da86..f8c1f643a0c 100644 --- a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java +++ b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java @@ -25,14 +25,11 @@ import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.pm.PackageManager; -import android.content.pm.ServiceInfo; import android.credentials.CredentialManager; -import android.credentials.ListEnabledProvidersException; -import android.credentials.ListEnabledProvidersResponse; +import android.credentials.CredentialProviderInfo; import android.credentials.SetEnabledProvidersException; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.os.CancellationSignal; import android.os.OutcomeReceiver; import android.os.UserHandle; import android.util.IconDrawableFactory; @@ -71,10 +68,9 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl private final PackageManager mPm; private final IconDrawableFactory mIconFactory; - private final List mServices; + private final List mServices; private final Set mEnabledPackageNames; private final @Nullable CredentialManager mCredentialManager; - private final CancellationSignal mCancellationSignal = new CancellationSignal(); private final Executor mExecutor; private final Map mPrefs = new HashMap<>(); // key is package name @@ -132,42 +128,20 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl lifecycleOwner, mCredentialManager.getCredentialProviderServices( getUser(), CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY)); - - mCredentialManager.listEnabledProviders( - mCancellationSignal, - mExecutor, - new OutcomeReceiver() { - @Override - public void onResult(ListEnabledProvidersResponse result) { - Set enabledPackages = new HashSet<>(); - for (String flattenedComponentName : result.getProviderComponentNames()) { - ComponentName cn = - ComponentName.unflattenFromString(flattenedComponentName); - if (cn != null) { - enabledPackages.add(cn.getPackageName()); - } - } - - setEnabledPackageNames(enabledPackages); - } - - @Override - public void onError(ListEnabledProvidersException e) { - Log.e(TAG, "listEnabledProviders error: " + e.toString()); - } - }); } @VisibleForTesting - void setAvailableServices(LifecycleOwner lifecycleOwner, List availableServices) { + void setAvailableServices( + LifecycleOwner lifecycleOwner, List availableServices) { mServices.clear(); mServices.addAll(availableServices); - } - @VisibleForTesting - void setEnabledPackageNames(Set enabledPackages) { mEnabledPackageNames.clear(); - mEnabledPackageNames.addAll(enabledPackages); + for (CredentialProviderInfo cpi : availableServices) { + if (cpi.isEnabled()) { + mEnabledPackageNames.add(cpi.getServiceInfo().packageName); + } + } for (String packageName : mPrefs.keySet()) { mPrefs.get(packageName).setChecked(mEnabledPackageNames.contains(packageName)); @@ -189,22 +163,22 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl PreferenceGroup group = screen.findPreference(getPreferenceKey()); Context context = screen.getContext(); - for (ServiceInfo serviceInfo : mServices) { - CharSequence title = ""; - if (serviceInfo.nonLocalizedLabel != null) { - title = serviceInfo.loadLabel(mPm); - } - - group.addPreference( - addProviderPreference( - context, - title, - mIconFactory.getBadgedIcon( - serviceInfo, serviceInfo.applicationInfo, getUser()), - serviceInfo.packageName)); + for (CredentialProviderInfo service : mServices) { + group.addPreference(createPreference(context, service)); } } + /** Creates a preference object based on the provider info. */ + @VisibleForTesting + public SwitchPreference createPreference(Context context, CredentialProviderInfo service) { + CharSequence label = service.getLabel(context); + return addProviderPreference( + context, + label == null ? "" : label, + service.getServiceIcon(mContext), + service.getServiceInfo().packageName); + } + /** * Enables the package name as an enabled credential manager provider. * @@ -246,9 +220,10 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl public List getEnabledSettings() { // Get all the component names that match the enabled package names. List enabledServices = new ArrayList<>(); - for (ServiceInfo service : mServices) { - if (mEnabledPackageNames.contains(service.packageName)) { - enabledServices.add(service.getComponentName().flattenToString()); + for (CredentialProviderInfo service : mServices) { + ComponentName cn = service.getServiceInfo().getComponentName(); + if (mEnabledPackageNames.contains(service.getServiceInfo().packageName)) { + enabledServices.add(cn.flattenToString()); } } 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 ff7e71a948f..2633ea7ad40 100644 --- a/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java @@ -27,12 +27,14 @@ import static org.mockito.Mockito.spy; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.ServiceInfo; +import android.credentials.CredentialProviderInfo; import android.os.Looper; import androidx.lifecycle.Lifecycle; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; +import androidx.preference.SwitchPreference; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -87,7 +89,7 @@ public class CredentialManagerPreferenceControllerTest { @Test public void getAvailabilityStatus_withServices_returnsAvailable() { CredentialManagerPreferenceController controller = - createControllerWithServices(Lists.newArrayList(createServiceInfo())); + createControllerWithServices(Lists.newArrayList(createCredentialProviderInfo())); assertThat(controller.isConnected()).isFalse(); assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE); } @@ -103,24 +105,59 @@ public class CredentialManagerPreferenceControllerTest { @Test public void displayPreference_withServices_preferencesAdded() { CredentialManagerPreferenceController controller = - createControllerWithServices(Lists.newArrayList(createServiceInfo())); + createControllerWithServices(Lists.newArrayList(createCredentialProviderInfo())); controller.displayPreference(mScreen); assertThat(controller.isConnected()).isFalse(); assertThat(mCredentialsPreferenceCategory.getPreferenceCount()).isEqualTo(1); } + @Test + public void buildSwitchPreference() { + CredentialProviderInfo providerInfo1 = + createCredentialProviderInfo( + "com.android.provider1", "ClassA", "Service Title", false); + CredentialProviderInfo providerInfo2 = + createCredentialProviderInfo( + "com.android.provider2", "ClassA", "Service Title", false); + CredentialManagerPreferenceController controller = + createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2)); + assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE); + assertThat(controller.isConnected()).isFalse(); + + // Test the data is correct. + assertThat(providerInfo1.isEnabled()).isFalse(); + assertThat(providerInfo2.isEnabled()).isFalse(); + assertThat(controller.getEnabledProviders().size()).isEqualTo(0); + + // Toggle one provider and make sure it worked. + assertThat(controller.togglePackageNameEnabled("com.android.provider1")).isTrue(); + Set enabledProviders = controller.getEnabledProviders(); + assertThat(enabledProviders.size()).isEqualTo(1); + assertThat(enabledProviders.contains("com.android.provider1")).isTrue(); + + // Create the pref (checked). + SwitchPreference pref = controller.createPreference(mContext, providerInfo1); + assertThat(pref.getTitle().toString()).isEqualTo("Service Title"); + assertThat(pref.isChecked()).isTrue(); + + // Create the pref (not checked). + SwitchPreference pref2 = controller.createPreference(mContext, providerInfo2); + assertThat(pref2.getTitle().toString()).isEqualTo("Service Title"); + assertThat(pref2.isChecked()).isFalse(); + } + @Test public void getAvailabilityStatus_handlesToggleAndSave() { CredentialManagerPreferenceController controller = createControllerWithServices( Lists.newArrayList( - createServiceInfo("com.android.provider1", "ClassA"), - createServiceInfo("com.android.provider1", "ClassB"), - createServiceInfo("com.android.provider2", "ClassA"), - createServiceInfo("com.android.provider3", "ClassA"), - createServiceInfo("com.android.provider4", "ClassA"), - createServiceInfo("com.android.provider5", "ClassA"), - createServiceInfo("com.android.provider6", "ClassA"))); + createCredentialProviderInfo("com.android.provider1", "ClassA"), + createCredentialProviderInfo("com.android.provider1", "ClassB"), + createCredentialProviderInfo("com.android.provider2", "ClassA"), + createCredentialProviderInfo("com.android.provider3", "ClassA"), + createCredentialProviderInfo("com.android.provider4", "ClassA"), + createCredentialProviderInfo("com.android.provider5", "ClassA"), + createCredentialProviderInfo("com.android.provider6", "ClassA"))); assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE); assertThat(controller.isConnected()).isFalse(); @@ -177,8 +214,38 @@ public class CredentialManagerPreferenceControllerTest { assertThat(currentlyEnabledServices.contains("com.android.provider6/ClassA")).isFalse(); } + @Test + public void handlesCredentialProviderInfoEnabledDisabled() { + CredentialProviderInfo providerInfo1 = + createCredentialProviderInfo( + "com.android.provider1", "ClassA", "Service Title", false); + CredentialProviderInfo providerInfo2 = + createCredentialProviderInfo( + "com.android.provider2", "ClassA", "Service Title", true); + CredentialManagerPreferenceController controller = + createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2)); + assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE); + assertThat(controller.isConnected()).isFalse(); + + // Test the data is correct. + assertThat(providerInfo1.isEnabled()).isFalse(); + assertThat(providerInfo2.isEnabled()).isTrue(); + + // Check that they are all actually registered. + Set enabledProviders = controller.getEnabledProviders(); + assertThat(enabledProviders.size()).isEqualTo(1); + assertThat(enabledProviders.contains("com.android.provider1")).isFalse(); + assertThat(enabledProviders.contains("com.android.provider2")).isTrue(); + + // Check that the settings string has the right component names. + List enabledServices = controller.getEnabledSettings(); + assertThat(enabledServices.size()).isEqualTo(1); + assertThat(enabledServices.contains("com.android.provider1/ClassA")).isFalse(); + assertThat(enabledServices.contains("com.android.provider2/ClassA")).isTrue(); + } + private CredentialManagerPreferenceController createControllerWithServices( - List availableServices) { + List availableServices) { CredentialManagerPreferenceController controller = new CredentialManagerPreferenceController( mContext, mCredentialsPreferenceCategory.getKey()); @@ -186,11 +253,17 @@ public class CredentialManagerPreferenceControllerTest { return controller; } - private ServiceInfo createServiceInfo() { - return createServiceInfo("com.android.provider", "CredManProvider"); + private CredentialProviderInfo createCredentialProviderInfo() { + return createCredentialProviderInfo("com.android.provider", "CredManProvider"); } - private ServiceInfo createServiceInfo(String packageName, String className) { + private CredentialProviderInfo createCredentialProviderInfo( + String packageName, String className) { + return createCredentialProviderInfo(packageName, className, null, false); + } + + private CredentialProviderInfo createCredentialProviderInfo( + String packageName, String className, CharSequence label, boolean isEnabled) { ServiceInfo si = new ServiceInfo(); si.packageName = packageName; si.name = className; @@ -200,6 +273,9 @@ public class CredentialManagerPreferenceControllerTest { si.applicationInfo.packageName = packageName; si.applicationInfo.nonLocalizedLabel = "test"; - return si; + return new CredentialProviderInfo.Builder(si) + .setOverrideLabel(label) + .setEnabled(isEnabled) + .build(); } }