diff --git a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java index 37c8f4ffaa0..157fee19776 100644 --- a/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java +++ b/src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java @@ -27,6 +27,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.content.res.Resources; @@ -82,15 +83,16 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl public static final String ADD_SERVICE_DEVICE_CONFIG = "credential_manager_service_search_uri"; private static final String TAG = "CredentialManagerPreferenceController"; private static final String ALTERNATE_INTENT = "android.settings.SYNC_SETTINGS"; + private static final String PRIMARY_INTENT = "android.settings.CREDENTIAL_PROVIDER"; private static final int MAX_SELECTABLE_PROVIDERS = 5; private final PackageManager mPm; private final IconDrawableFactory mIconFactory; private final List mServices; - private final Set mEnabledServiceInfos; + private final Set mEnabledPackageNames; private final @Nullable CredentialManager mCredentialManager; private final Executor mExecutor; - private final Map mPrefs = new HashMap<>(); + private final Map mPrefs = new HashMap<>(); // key is package name private final List mPendingServiceInfos = new ArrayList<>(); private final Handler mHandler = new Handler(); @@ -104,7 +106,7 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl mPm = context.getPackageManager(); mIconFactory = IconDrawableFactory.newInstance(mContext); mServices = new ArrayList<>(); - mEnabledServiceInfos = new HashSet<>(); + mEnabledPackageNames = new HashSet<>(); mExecutor = ContextCompat.getMainExecutor(mContext); mCredentialManager = getCredentialManager(context, preferenceKey.equals("credentials_test")); @@ -161,8 +163,7 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl } final String action = launchIntent.getAction(); - final boolean isCredProviderAction = - TextUtils.equals(action, Settings.ACTION_CREDENTIAL_PROVIDER); + final boolean isCredProviderAction = TextUtils.equals(action, PRIMARY_INTENT); final boolean isExistingAction = TextUtils.equals(action, ALTERNATE_INTENT); final boolean isValid = isCredProviderAction || isExistingAction; @@ -222,18 +223,20 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl } ServiceInfo serviceInfo = pendingServiceInfos.get(0); - CharSequence serviceLabel = ""; - if (serviceInfo.nonLocalizedLabel != null) { - serviceLabel = serviceInfo.loadLabel(mPm); + ApplicationInfo appInfo = serviceInfo.applicationInfo; + CharSequence appName = ""; + if (appInfo.nonLocalizedLabel != null) { + appName = appInfo.loadLabel(mPm); } - // Stop if there is no service label. - if (TextUtils.isEmpty(serviceLabel)) { + // Stop if there is no name. + if (TextUtils.isEmpty(appName)) { return; } NewProviderConfirmationDialogFragment fragment = - newNewProviderConfirmationDialogFragment(serviceInfo, serviceLabel, /* setActivityResult= */ true); + newNewProviderConfirmationDialogFragment( + serviceInfo.packageName, appName, /* setActivityResult= */ true); if (fragment == null || mFragmentManager == null) { return; } @@ -276,15 +279,15 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl // If there is a pending dialog then show it. handleIntent(); - mEnabledServiceInfos.clear(); + mEnabledPackageNames.clear(); for (CredentialProviderInfo cpi : availableServices) { if (cpi.isEnabled()) { - mEnabledServiceInfos.add(cpi.getServiceInfo()); + mEnabledPackageNames.add(cpi.getServiceInfo().packageName); } } - for (ServiceInfo serviceInfo : mPrefs.keySet()) { - mPrefs.get(serviceInfo).setChecked(mEnabledServiceInfos.contains(serviceInfo)); + for (String packageName : mPrefs.keySet()) { + mPrefs.get(packageName).setChecked(mEnabledPackageNames.contains(packageName)); } } @@ -367,7 +370,7 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl /** Aggregates the list of services and builds a list of UI prefs to show. */ @VisibleForTesting - public Map buildPreferenceList( + public Map buildPreferenceList( Context context, PreferenceGroup group) { // Group the services by package name. Map> groupedInfos = new HashMap<>(); @@ -385,11 +388,33 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl } // Build the pref list. - Map output = new HashMap<>(); - for (CredentialProviderInfo service : mServices) { + Map output = new HashMap<>(); + for (String packageName : groupedInfos.keySet()) { + List infos = groupedInfos.get(packageName); + CredentialProviderInfo firstInfo = infos.get(0); + ServiceInfo firstServiceInfo = firstInfo.getServiceInfo(); + CharSequence title = firstInfo.getLabel(context); + Drawable icon = firstInfo.getServiceIcon(context); + + if (infos.size() > 1) { + // If there is more than one then group them under the package. + ApplicationInfo appInfo = firstServiceInfo.applicationInfo; + if (appInfo.nonLocalizedLabel != null) { + title = appInfo.loadLabel(mPm); + } + icon = mIconFactory.getBadgedIcon(appInfo, getUser()); + } + + // If there is no title then show the package manager. + if (TextUtils.isEmpty(title)) { + title = firstServiceInfo.packageName; + } + // Build the pref and add it to the output & group. - SwitchPreference pref = createPreference(mContext, service); - output.put(service.getServiceInfo(), pref); + SwitchPreference pref = + addProviderPreference( + context, title, icon, packageName, firstInfo.getSettingsSubtitle()); + output.put(packageName, pref); group.addPreference(pref); } @@ -399,54 +424,46 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl /** Creates a preference object based on the provider info. */ @VisibleForTesting public SwitchPreference createPreference(Context context, CredentialProviderInfo service) { - final String packageName = service.getServiceInfo().packageName; CharSequence label = service.getLabel(context); - - // If there is no label then show the package name. - if (label == null || TextUtils.isEmpty(label)) { - label = packageName; - } - return addProviderPreference( context, - label, + label == null ? "" : label, service.getServiceIcon(mContext), - packageName, - service.getSettingsSubtitle(), - service.getServiceInfo()); + service.getServiceInfo().packageName, + service.getSettingsSubtitle()); } /** - * Enables the service as an enabled credential manager provider. + * Enables the package name as an enabled credential manager provider. * - * @param service the service to enable + * @param packageName the package name to enable */ @VisibleForTesting - public boolean toggleServiceInfoEnabled(ServiceInfo service) { - if (mEnabledServiceInfos.size() >= MAX_SELECTABLE_PROVIDERS) { + public boolean togglePackageNameEnabled(String packageName) { + if (mEnabledPackageNames.size() >= MAX_SELECTABLE_PROVIDERS) { return false; } else { - mEnabledServiceInfos.add(service); - commitEnabledServices(); + mEnabledPackageNames.add(packageName); + commitEnabledPackages(); return true; } } /** - * Disables the service as a credential manager provider. + * Disables the package name as a credential manager provider. * - * @param service the service to disable + * @param packageName the package name to disable */ @VisibleForTesting - public void toggleServiceInfoDisabled(ServiceInfo service) { - mEnabledServiceInfos.remove(service); - commitEnabledServices(); + public void togglePackageNameDisabled(String packageName) { + mEnabledPackageNames.remove(packageName); + commitEnabledPackages(); } /** Returns the enabled credential manager provider package names. */ @VisibleForTesting - public Set getEnabledProviders() { - return mEnabledServiceInfos; + public Set getEnabledProviders() { + return mEnabledPackageNames; } /** @@ -457,8 +474,11 @@ 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 : mEnabledServiceInfos) { - enabledServices.add(service.getComponentName().flattenToString()); + for (CredentialProviderInfo service : mServices) { + ComponentName cn = service.getServiceInfo().getComponentName(); + if (mEnabledPackageNames.contains(service.getServiceInfo().packageName)) { + enabledServices.add(cn.flattenToString()); + } } return enabledServices; @@ -469,11 +489,10 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl @NonNull CharSequence title, @Nullable Drawable icon, @NonNull String packageName, - @Nullable CharSequence subtitle, - @NonNull ServiceInfo service) { + @Nullable CharSequence subtitle) { final SwitchPreference pref = new SwitchPreference(prefContext); pref.setTitle(title); - pref.setChecked(mEnabledServiceInfos.contains(service)); + pref.setChecked(mEnabledPackageNames.contains(packageName)); if (icon != null) { pref.setIcon(Utils.getSafeIcon(icon)); @@ -492,7 +511,7 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl // dialog box. NewProviderConfirmationDialogFragment fragment = newNewProviderConfirmationDialogFragment( - service, title, /* setActivityResult= */ false); + packageName, title, /* setActivityResult= */ false); if (fragment == null || mFragmentManager == null) { return true; } @@ -502,9 +521,9 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl return true; } else { // If we are disabling the last enabled provider then show a warning. - if (mEnabledServiceInfos.size() <= 1) { + if (mEnabledPackageNames.size() <= 1) { final DialogFragment fragment = - newConfirmationDialogFragment(service, title, pref); + newConfirmationDialogFragment(packageName, title, pref); if (fragment == null || mFragmentManager == null) { return true; @@ -512,7 +531,7 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl fragment.show(mFragmentManager, ConfirmationDialogFragment.TAG); } else { - toggleServiceInfoDisabled(service); + togglePackageNameDisabled(packageName); } } @@ -522,7 +541,7 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl return pref; } - private void commitEnabledServices() { + private void commitEnabledPackages() { // Commit using the CredMan API. if (mCredentialManager == null) { return; @@ -549,18 +568,19 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl /** Create the new provider confirmation dialog. */ private @Nullable NewProviderConfirmationDialogFragment newNewProviderConfirmationDialogFragment( - @NonNull ServiceInfo service, + @NonNull String packageName, @NonNull CharSequence appName, boolean setActivityResult) { DialogHost host = new DialogHost() { @Override public void onDialogClick(int whichButton) { - completeEnableProviderDialogBox(whichButton, service, setActivityResult); + completeEnableProviderDialogBox( + whichButton, packageName, setActivityResult); } }; - return new NewProviderConfirmationDialogFragment(host, service, appName); + return new NewProviderConfirmationDialogFragment(host, packageName, appName); } /** If the provider is also the autofill provider then hide it. */ @@ -581,13 +601,14 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl } @VisibleForTesting - void completeEnableProviderDialogBox(int whichButton, ServiceInfo service, boolean setActivityResult) { + void completeEnableProviderDialogBox( + int whichButton, String packageName, boolean setActivityResult) { int activityResult = -1; if (whichButton == DialogInterface.BUTTON_POSITIVE) { - if (toggleServiceInfoEnabled(service)) { + if (togglePackageNameEnabled(packageName)) { // Enable all prefs. - if (mPrefs.containsKey(service)) { - mPrefs.get(service).setChecked(true); + if (mPrefs.containsKey(packageName)) { + mPrefs.get(packageName).setChecked(true); } activityResult = Activity.RESULT_OK; } else { @@ -626,7 +647,7 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl } private @Nullable ConfirmationDialogFragment newConfirmationDialogFragment( - @NonNull ServiceInfo service, + @NonNull String packageName, @NonNull CharSequence appName, @NonNull SwitchPreference pref) { DialogHost host = @@ -636,7 +657,7 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl if (whichButton == DialogInterface.BUTTON_POSITIVE) { // Since the package is now enabled then we // should remove it from the enabled list. - toggleServiceInfoDisabled(service); + togglePackageNameDisabled(packageName); } else if (whichButton == DialogInterface.BUTTON_NEGATIVE) { // Set the checked back to true because we // backed out of turning this off. @@ -645,7 +666,7 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl } }; - return new ConfirmationDialogFragment(host, service, appName); + return new ConfirmationDialogFragment(host, packageName, appName); } private int getUser() { @@ -730,13 +751,11 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl public static class ConfirmationDialogFragment extends CredentialManagerDialogFragment { ConfirmationDialogFragment( - DialogHost dialogHost, - @NonNull ServiceInfo serviceInfo, - @NonNull CharSequence appName) { + DialogHost dialogHost, @NonNull String packageName, @NonNull CharSequence appName) { super(dialogHost); final Bundle argument = new Bundle(); - argument.putString(PACKAGE_NAME_KEY, serviceInfo.packageName); + argument.putString(PACKAGE_NAME_KEY, packageName); argument.putCharSequence(APP_NAME_KEY, appName); setArguments(argument); } @@ -773,13 +792,11 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl extends CredentialManagerDialogFragment { NewProviderConfirmationDialogFragment( - DialogHost dialogHost, - @NonNull ServiceInfo service, - @NonNull CharSequence appName) { + DialogHost dialogHost, @NonNull String packageName, @NonNull CharSequence appName) { super(dialogHost); final Bundle argument = new Bundle(); - argument.putString(PACKAGE_NAME_KEY, service.packageName); + argument.putString(PACKAGE_NAME_KEY, packageName); argument.putCharSequence(APP_NAME_KEY, appName); setArguments(argument); } @@ -832,4 +849,4 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl updateFromExternal(); } } -} +} \ No newline at end of file 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 dd928108c3f..a97d5f7345d 100644 --- a/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java @@ -51,9 +51,9 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; @@ -72,6 +72,8 @@ public class CredentialManagerPreferenceControllerTest { private static final String TEST_TITLE_APP_A = "test app A"; private static final String TEST_TITLE_APP_B = "test app B"; private static final String TEST_TITLE_SERVICE_C = "test service C1"; + private static final String PRIMARY_INTENT = "android.settings.CREDENTIAL_PROVIDER"; + private static final String ALTERNATE_INTENT = "android.settings.SYNC_SETTINGS"; @Before public void setUp() { @@ -193,10 +195,10 @@ public class CredentialManagerPreferenceControllerTest { @Test public void buildSwitchPreference() { CredentialProviderInfo providerInfo1 = - createCredentialProviderInfoWithSettingsSubtitle( + createCredentialProviderInfoWithSubtitle( "com.android.provider1", "ClassA", "Service Title", null); CredentialProviderInfo providerInfo2 = - createCredentialProviderInfoWithSettingsSubtitle( + createCredentialProviderInfoWithSubtitle( "com.android.provider2", "ClassA", "Service Title", "Summary Text"); CredentialManagerPreferenceController controller = createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2)); @@ -209,10 +211,10 @@ public class CredentialManagerPreferenceControllerTest { assertThat(controller.getEnabledProviders().size()).isEqualTo(0); // Toggle one provider and make sure it worked. - assertThat(controller.toggleServiceInfoEnabled(providerInfo1.getServiceInfo())).isTrue(); - Set enabledProviders = controller.getEnabledProviders(); + assertThat(controller.togglePackageNameEnabled("com.android.provider1")).isTrue(); + Set enabledProviders = controller.getEnabledProviders(); assertThat(enabledProviders.size()).isEqualTo(1); - assertThat(enabledProviders.contains(providerInfo1.getServiceInfo())).isTrue(); + assertThat(enabledProviders.contains("com.android.provider1")).isTrue(); // Create the pref (checked). SwitchPreference pref = controller.createPreference(mContext, providerInfo1); @@ -221,8 +223,7 @@ public class CredentialManagerPreferenceControllerTest { assertThat(pref.getSummary()).isNull(); // Create the pref (not checked). - SwitchPreference pref2 = - controller.createPreference(mContext, providerInfo2); + SwitchPreference pref2 = controller.createPreference(mContext, providerInfo2); assertThat(pref2.getTitle().toString()).isEqualTo("Service Title"); assertThat(pref2.isChecked()).isFalse(); assertThat(pref2.getSummary().toString()).isEqualTo("Summary Text"); @@ -230,14 +231,6 @@ public class CredentialManagerPreferenceControllerTest { @Test public void getAvailabilityStatus_handlesToggleAndSave() { - ServiceInfo providerService1a = createServiceInfo("com.android.provider1", "ClassA"); - ServiceInfo providerService1b = createServiceInfo("com.android.provider1", "ClassB"); - ServiceInfo providerService2 = createServiceInfo("com.android.provider2", "ClassA"); - ServiceInfo providerService3 = createServiceInfo("com.android.provider3", "ClassA"); - ServiceInfo providerService4 = createServiceInfo("com.android.provider4", "ClassA"); - ServiceInfo providerService5 = createServiceInfo("com.android.provider5", "ClassA"); - ServiceInfo providerService6 = createServiceInfo("com.android.provider6", "ClassA"); - CredentialManagerPreferenceController controller = createControllerWithServices( Lists.newArrayList( @@ -252,28 +245,28 @@ public class CredentialManagerPreferenceControllerTest { assertThat(controller.isConnected()).isFalse(); // Ensure that we stay under 5 providers. - assertThat(controller.toggleServiceInfoEnabled(providerService1a)).isTrue(); - assertThat(controller.toggleServiceInfoEnabled(providerService2)).isTrue(); - assertThat(controller.toggleServiceInfoEnabled(providerService3)).isTrue(); - assertThat(controller.toggleServiceInfoEnabled(providerService4)).isTrue(); - assertThat(controller.toggleServiceInfoEnabled(providerService5)).isTrue(); - assertThat(controller.toggleServiceInfoEnabled(providerService6)).isFalse(); + assertThat(controller.togglePackageNameEnabled("com.android.provider1")).isTrue(); + assertThat(controller.togglePackageNameEnabled("com.android.provider2")).isTrue(); + assertThat(controller.togglePackageNameEnabled("com.android.provider3")).isTrue(); + assertThat(controller.togglePackageNameEnabled("com.android.provider4")).isTrue(); + assertThat(controller.togglePackageNameEnabled("com.android.provider5")).isTrue(); + assertThat(controller.togglePackageNameEnabled("com.android.provider6")).isFalse(); // Check that they are all actually registered. - Set enabledProviders = controller.getEnabledProviders(); + Set enabledProviders = controller.getEnabledProviders(); assertThat(enabledProviders.size()).isEqualTo(5); - assertThat(enabledProviders.contains(providerService1a)).isTrue(); - assertThat(enabledProviders.contains(providerService2)).isTrue(); - assertThat(enabledProviders.contains(providerService3)).isTrue(); - assertThat(enabledProviders.contains(providerService4)).isTrue(); - assertThat(enabledProviders.contains(providerService5)).isTrue(); - assertThat(enabledProviders.contains(providerService6)).isFalse(); + assertThat(enabledProviders.contains("com.android.provider1")).isTrue(); + assertThat(enabledProviders.contains("com.android.provider2")).isTrue(); + assertThat(enabledProviders.contains("com.android.provider3")).isTrue(); + assertThat(enabledProviders.contains("com.android.provider4")).isTrue(); + assertThat(enabledProviders.contains("com.android.provider5")).isTrue(); + assertThat(enabledProviders.contains("com.android.provider6")).isFalse(); // Check that the settings string has the right component names. List enabledServices = controller.getEnabledSettings(); - assertThat(enabledServices.size()).isEqualTo(5); + assertThat(enabledServices.size()).isEqualTo(6); assertThat(enabledServices.contains("com.android.provider1/ClassA")).isTrue(); - assertThat(enabledServices.contains("com.android.provider1/ClassB")).isFalse(); + assertThat(enabledServices.contains("com.android.provider1/ClassB")).isTrue(); assertThat(enabledServices.contains("com.android.provider2/ClassA")).isTrue(); assertThat(enabledServices.contains("com.android.provider3/ClassA")).isTrue(); assertThat(enabledServices.contains("com.android.provider4/ClassA")).isTrue(); @@ -281,24 +274,23 @@ public class CredentialManagerPreferenceControllerTest { assertThat(enabledServices.contains("com.android.provider6/ClassA")).isFalse(); // Toggle the provider disabled. - controller.toggleServiceInfoDisabled(providerService2); + controller.togglePackageNameDisabled("com.android.provider2"); // Check that the provider was removed from the list of providers. - Set currentlyEnabledProviders = controller.getEnabledProviders(); + Set currentlyEnabledProviders = controller.getEnabledProviders(); assertThat(currentlyEnabledProviders.size()).isEqualTo(4); - assertThat(enabledProviders.contains(providerService1a)).isTrue(); - assertThat(enabledProviders.contains(providerService2)).isFalse(); - assertThat(enabledProviders.contains(providerService3)).isTrue(); - assertThat(enabledProviders.contains(providerService4)).isTrue(); - assertThat(enabledProviders.contains(providerService5)).isTrue(); - assertThat(enabledProviders.contains(providerService6)).isFalse(); + assertThat(currentlyEnabledProviders.contains("com.android.provider1")).isTrue(); + assertThat(currentlyEnabledProviders.contains("com.android.provider2")).isFalse(); + assertThat(currentlyEnabledProviders.contains("com.android.provider3")).isTrue(); + assertThat(currentlyEnabledProviders.contains("com.android.provider4")).isTrue(); + assertThat(currentlyEnabledProviders.contains("com.android.provider5")).isTrue(); + assertThat(currentlyEnabledProviders.contains("com.android.provider6")).isFalse(); // Check that the provider was removed from the list of services stored in the setting. List currentlyEnabledServices = controller.getEnabledSettings(); - assertThat(currentlyEnabledServices.size()).isEqualTo(4); + assertThat(currentlyEnabledServices.size()).isEqualTo(5); assertThat(currentlyEnabledServices.contains("com.android.provider1/ClassA")).isTrue(); - assertThat(currentlyEnabledServices.contains("com.android.provider1/ClassB")).isFalse(); - assertThat(currentlyEnabledServices.contains("com.android.provider2/ClassA")).isFalse(); + assertThat(currentlyEnabledServices.contains("com.android.provider1/ClassB")).isTrue(); assertThat(currentlyEnabledServices.contains("com.android.provider3/ClassA")).isTrue(); assertThat(currentlyEnabledServices.contains("com.android.provider4/ClassA")).isTrue(); assertThat(currentlyEnabledServices.contains("com.android.provider5/ClassA")).isTrue(); @@ -307,8 +299,6 @@ public class CredentialManagerPreferenceControllerTest { @Test public void handlesCredentialProviderInfoEnabledDisabled() { - ServiceInfo providerService1 = createServiceInfo("com.android.provider1", "ClassA"); - ServiceInfo providerService2 = createServiceInfo("com.android.provider2", "ClassA"); CredentialProviderInfo providerInfo1 = createCredentialProviderInfoWithIsEnabled( "com.android.provider1", "ClassA", "Service Title", false); @@ -325,10 +315,10 @@ public class CredentialManagerPreferenceControllerTest { assertThat(providerInfo2.isEnabled()).isTrue(); // Check that they are all actually registered. - Set enabledProviders = controller.getEnabledProviders(); + Set enabledProviders = controller.getEnabledProviders(); assertThat(enabledProviders.size()).isEqualTo(1); - assertThat(enabledProviders.contains(providerInfo1.getServiceInfo())).isFalse(); - assertThat(enabledProviders.contains(providerInfo2.getServiceInfo())).isTrue(); + 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(); @@ -337,6 +327,65 @@ public class CredentialManagerPreferenceControllerTest { assertThat(enabledServices.contains("com.android.provider2/ClassA")).isTrue(); } + @Test + public void displayPreference_withServices_preferencesAdded_sameAppShouldBeMerged() { + CredentialProviderInfo serviceA1 = + createCredentialProviderInfoWithAppLabel( + TEST_PACKAGE_NAME_A, + "CredManProviderA1", + TEST_TITLE_APP_A, + "test service A1"); + CredentialProviderInfo serviceB1 = + createCredentialProviderInfoWithAppLabel( + TEST_PACKAGE_NAME_B, + "CredManProviderB1", + TEST_TITLE_APP_B, + "test service B"); + CredentialProviderInfo serviceC1 = + createCredentialProviderInfoWithAppLabel( + TEST_PACKAGE_NAME_C, + "CredManProviderC1", + "test app C1", + TEST_TITLE_SERVICE_C); + CredentialProviderInfo serviceC2 = + createCredentialProviderInfoWithAppLabel( + TEST_PACKAGE_NAME_C, + "CredManProviderC2", + "test app C2", + TEST_TITLE_SERVICE_C); + CredentialProviderInfo serviceC3 = + createCredentialProviderInfoBuilder( + TEST_PACKAGE_NAME_C, + "CredManProviderC3", + "test app C3", + TEST_TITLE_SERVICE_C) + .setEnabled(true) + .build(); + + CredentialManagerPreferenceController controller = + createControllerWithServices( + Lists.newArrayList(serviceA1, serviceB1, serviceC1, serviceC2, serviceC3)); + controller.displayPreference(mScreen); + + assertThat(controller.isConnected()).isFalse(); + assertThat(mCredentialsPreferenceCategory.getPreferenceCount()).isEqualTo(3); + + Map prefs = + controller.buildPreferenceList(mContext, mCredentialsPreferenceCategory); + assertThat(prefs.keySet()) + .containsExactly(TEST_PACKAGE_NAME_A, TEST_PACKAGE_NAME_B, TEST_PACKAGE_NAME_C); + assertThat(prefs.size()).isEqualTo(3); + assertThat(prefs.containsKey(TEST_PACKAGE_NAME_A)).isTrue(); + assertThat(prefs.get(TEST_PACKAGE_NAME_A).getTitle()).isEqualTo(TEST_TITLE_APP_A); + assertThat(prefs.get(TEST_PACKAGE_NAME_A).isChecked()).isFalse(); + assertThat(prefs.containsKey(TEST_PACKAGE_NAME_B)).isTrue(); + assertThat(prefs.get(TEST_PACKAGE_NAME_B).getTitle()).isEqualTo(TEST_TITLE_APP_B); + assertThat(prefs.get(TEST_PACKAGE_NAME_B).isChecked()).isFalse(); + assertThat(prefs.containsKey(TEST_PACKAGE_NAME_C)).isTrue(); + assertThat(prefs.get(TEST_PACKAGE_NAME_C).getTitle()).isEqualTo(TEST_TITLE_SERVICE_C); + assertThat(prefs.get(TEST_PACKAGE_NAME_C).isChecked()).isTrue(); + } + @Test public void handleIntentWithProviderServiceInfo_handleBadIntent_missingData() { CredentialProviderInfo cpi = createCredentialProviderInfo(); @@ -344,7 +393,7 @@ public class CredentialManagerPreferenceControllerTest { createControllerWithServices(Lists.newArrayList(cpi)); // Create an intent with missing data. - Intent missingDataIntent = new Intent(Settings.ACTION_CREDENTIAL_PROVIDER); + Intent missingDataIntent = new Intent(PRIMARY_INTENT); assertThat(controller.verifyReceivedIntent(missingDataIntent)).isFalse(); } @@ -356,11 +405,10 @@ public class CredentialManagerPreferenceControllerTest { String packageName = cpi.getServiceInfo().packageName; // Create an intent with valid data. - Intent intent = new Intent(Settings.ACTION_CREDENTIAL_PROVIDER); + Intent intent = new Intent(PRIMARY_INTENT); intent.setData(Uri.parse("package:" + packageName)); assertThat(controller.verifyReceivedIntent(intent)).isTrue(); - controller.completeEnableProviderDialogBox( - DialogInterface.BUTTON_POSITIVE, cpi.getServiceInfo(), true); + controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_POSITIVE, packageName, true); assertThat(mReceivedResultCode.get()).isEqualTo(Activity.RESULT_OK); } @@ -372,10 +420,51 @@ public class CredentialManagerPreferenceControllerTest { String packageName = cpi.getServiceInfo().packageName; // Create an intent with valid data. - Intent intent = new Intent(Settings.ACTION_CREDENTIAL_PROVIDER); + Intent intent = new Intent(PRIMARY_INTENT); intent.setData(Uri.parse("package:" + packageName)); assertThat(controller.verifyReceivedIntent(intent)).isTrue(); - controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_NEGATIVE, cpi.getServiceInfo(), true); + controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_NEGATIVE, packageName, true); + assertThat(mReceivedResultCode.get()).isEqualTo(Activity.RESULT_CANCELED); + } + + @Test + public void handleOtherIntentWithProviderServiceInfo_handleBadIntent_missingData() { + CredentialProviderInfo cpi = createCredentialProviderInfo(); + CredentialManagerPreferenceController controller = + createControllerWithServices(Lists.newArrayList(cpi)); + + // Create an intent with missing data. + Intent missingDataIntent = new Intent(ALTERNATE_INTENT); + assertThat(controller.verifyReceivedIntent(missingDataIntent)).isFalse(); + } + + @Test + public void handleOtherIntentWithProviderServiceInfo_handleBadIntent_successDialog() { + CredentialProviderInfo cpi = createCredentialProviderInfo(); + CredentialManagerPreferenceController controller = + createControllerWithServices(Lists.newArrayList(cpi)); + String packageName = cpi.getServiceInfo().packageName; + + // Create an intent with valid data. + Intent intent = new Intent(ALTERNATE_INTENT); + intent.setData(Uri.parse("package:" + packageName)); + assertThat(controller.verifyReceivedIntent(intent)).isTrue(); + controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_POSITIVE, packageName, true); + assertThat(mReceivedResultCode.get()).isEqualTo(Activity.RESULT_OK); + } + + @Test + public void handleOtherIntentWithProviderServiceInfo_handleIntent_cancelDialog() { + CredentialProviderInfo cpi = createCredentialProviderInfo(); + CredentialManagerPreferenceController controller = + createControllerWithServices(Lists.newArrayList(cpi)); + String packageName = cpi.getServiceInfo().packageName; + + // Create an intent with valid data. + Intent intent = new Intent(ALTERNATE_INTENT); + intent.setData(Uri.parse("package:" + packageName)); + assertThat(controller.verifyReceivedIntent(intent)).isTrue(); + controller.completeEnableProviderDialogBox(DialogInterface.BUTTON_NEGATIVE, packageName, true); assertThat(mReceivedResultCode.get()).isEqualTo(Activity.RESULT_CANCELED); } @@ -429,17 +518,15 @@ public class CredentialManagerPreferenceControllerTest { .build(); } - private CredentialProviderInfo createCredentialProviderInfo( - String packageName, String className, CharSequence label, boolean isEnabled) { - return createCredentialProviderInfo(packageName, className, label, isEnabled, null); + private CredentialProviderInfo createCredentialProviderInfoWithIsEnabled( + String packageName, String className, CharSequence serviceLabel, boolean isEnabled) { + return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, "App Name") + .setEnabled(isEnabled) + .build(); } - private CredentialProviderInfo createCredentialProviderInfo( - String packageName, - String className, - CharSequence label, - boolean isEnabled, - CharSequence subtitle) { + private CredentialProviderInfo createCredentialProviderInfoWithSubtitle( + String packageName, String className, CharSequence label, CharSequence subtitle) { ServiceInfo si = new ServiceInfo(); si.packageName = packageName; si.name = className; @@ -455,20 +542,6 @@ public class CredentialManagerPreferenceControllerTest { .build(); } - private CredentialProviderInfo createCredentialProviderInfoWithIsEnabled( - String packageName, String className, CharSequence serviceLabel, boolean isEnabled) { - return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, "App Name") - .setEnabled(isEnabled) - .build(); - } - - private CredentialProviderInfo createCredentialProviderInfoWithSettingsSubtitle( - String packageName, String className, CharSequence serviceLabel, String subtitle) { - return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, "App Name") - .setSettingsSubtitle(subtitle) - .build(); - } - private CredentialProviderInfo createCredentialProviderInfoWithAppLabel( String packageName, String className, CharSequence serviceLabel, String appLabel) { return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, appLabel) @@ -488,14 +561,4 @@ public class CredentialManagerPreferenceControllerTest { return new CredentialProviderInfo.Builder(si).setOverrideLabel(serviceLabel); } - - private ServiceInfo createServiceInfo(String packageName, String className) { - ServiceInfo si = new ServiceInfo(); - si.packageName = packageName; - si.name = className; - - si.applicationInfo = new ApplicationInfo(); - si.applicationInfo.packageName = packageName; - return si; - } -} +} \ No newline at end of file