Loading src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java +49 −3 Original line number Diff line number Diff line Loading @@ -24,7 +24,9 @@ import android.app.Dialog; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.credentials.CredentialManager; import android.credentials.CredentialProviderInfo; import android.credentials.SetEnabledProvidersException; Loading @@ -32,6 +34,7 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.OutcomeReceiver; import android.os.UserHandle; import android.text.TextUtils; import android.util.IconDrawableFactory; import android.util.Log; Loading Loading @@ -162,10 +165,54 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl PreferenceGroup group = screen.findPreference(getPreferenceKey()); Context context = screen.getContext(); mPrefs.putAll(buildPreferenceList(context, group)); } for (CredentialProviderInfo service : mServices) { group.addPreference(createPreference(context, service)); /** Aggregates the list of services and builds a list of UI prefs to show. */ @VisibleForTesting public Map<String, SwitchPreference> buildPreferenceList( Context context, PreferenceGroup group) { // Group the services by package name. Map<String, List<CredentialProviderInfo>> groupedInfos = new HashMap<>(); for (CredentialProviderInfo cpi : mServices) { String packageName = cpi.getServiceInfo().packageName; if (!groupedInfos.containsKey(packageName)) { groupedInfos.put(packageName, new ArrayList<>()); } groupedInfos.get(packageName).add(cpi); } // Build the pref list. Map<String, SwitchPreference> output = new HashMap<>(); for (String packageName : groupedInfos.keySet()) { List<CredentialProviderInfo> 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 don't show anything. if (TextUtils.isEmpty(title)) { continue; } // Build the pref and add it to the output & group. SwitchPreference pref = addProviderPreference(context, title, icon, packageName); output.put(packageName, pref); group.addPreference(pref); } return output; } /** Creates a preference object based on the provider info. */ Loading Loading @@ -238,7 +285,6 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl final SwitchPreference pref = new SwitchPreference(prefContext); pref.setTitle(title); pref.setChecked(mEnabledPackageNames.contains(packageName)); mPrefs.put(packageName, pref); if (icon != null) { pref.setIcon(Utils.getSafeIcon(icon)); Loading tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java +89 −13 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import org.junit.runner.RunWith; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @RunWith(AndroidJUnit4.class) Loading @@ -55,6 +56,13 @@ public class CredentialManagerPreferenceControllerTest { private PreferenceScreen mScreen; private PreferenceCategory mCredentialsPreferenceCategory; private static final String TEST_PACKAGE_NAME_A = "com.android.providerA"; private static final String TEST_PACKAGE_NAME_B = "com.android.providerB"; private static final String TEST_PACKAGE_NAME_C = "com.android.providerC"; 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"; @Before public void setUp() { mContext = spy(ApplicationProvider.getApplicationContext()); Loading Loading @@ -114,10 +122,10 @@ public class CredentialManagerPreferenceControllerTest { @Test public void buildSwitchPreference() { CredentialProviderInfo providerInfo1 = createCredentialProviderInfo( createCredentialProviderInfoWithIsEnabled( "com.android.provider1", "ClassA", "Service Title", false); CredentialProviderInfo providerInfo2 = createCredentialProviderInfo( createCredentialProviderInfoWithIsEnabled( "com.android.provider2", "ClassA", "Service Title", false); CredentialManagerPreferenceController controller = createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2)); Loading Loading @@ -217,10 +225,10 @@ public class CredentialManagerPreferenceControllerTest { @Test public void handlesCredentialProviderInfoEnabledDisabled() { CredentialProviderInfo providerInfo1 = createCredentialProviderInfo( createCredentialProviderInfoWithIsEnabled( "com.android.provider1", "ClassA", "Service Title", false); CredentialProviderInfo providerInfo2 = createCredentialProviderInfo( createCredentialProviderInfoWithIsEnabled( "com.android.provider2", "ClassA", "Service Title", true); CredentialManagerPreferenceController controller = createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2)); Loading @@ -244,6 +252,63 @@ 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<String, SwitchPreference> prefs = controller.buildPreferenceList(mContext, mCredentialsPreferenceCategory); assertThat(prefs.size()).isEqualTo(3); assertThat(prefs.containsKey(TEST_PACKAGE_NAME_A)); 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)); 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)); assertThat(prefs.get(TEST_PACKAGE_NAME_C).getTitle()).isEqualTo(TEST_TITLE_SERVICE_C); assertThat(prefs.get(TEST_PACKAGE_NAME_C).isChecked()).isTrue(); } private CredentialManagerPreferenceController createControllerWithServices( List<CredentialProviderInfo> availableServices) { CredentialManagerPreferenceController controller = Loading @@ -259,23 +324,34 @@ public class CredentialManagerPreferenceControllerTest { private CredentialProviderInfo createCredentialProviderInfo( String packageName, String className) { return createCredentialProviderInfo(packageName, className, null, false); return createCredentialProviderInfoBuilder(packageName, className, null, "App Name") .build(); } private CredentialProviderInfo createCredentialProviderInfo( String packageName, String className, CharSequence label, boolean isEnabled) { private CredentialProviderInfo createCredentialProviderInfoWithIsEnabled( String packageName, String className, CharSequence serviceLabel, boolean isEnabled) { return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, "App Name") .setEnabled(isEnabled) .build(); } private CredentialProviderInfo createCredentialProviderInfoWithAppLabel( String packageName, String className, CharSequence serviceLabel, String appLabel) { return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, appLabel) .build(); } private CredentialProviderInfo.Builder createCredentialProviderInfoBuilder( String packageName, String className, CharSequence serviceLabel, String appLabel) { ServiceInfo si = new ServiceInfo(); si.packageName = packageName; si.name = className; si.nonLocalizedLabel = "test"; si.nonLocalizedLabel = serviceLabel; si.applicationInfo = new ApplicationInfo(); si.applicationInfo.packageName = packageName; si.applicationInfo.nonLocalizedLabel = "test"; si.applicationInfo.nonLocalizedLabel = appLabel; return new CredentialProviderInfo.Builder(si) .setOverrideLabel(label) .setEnabled(isEnabled) .build(); return new CredentialProviderInfo.Builder(si).setOverrideLabel(serviceLabel); } } Loading
src/com/android/settings/applications/credentials/CredentialManagerPreferenceController.java +49 −3 Original line number Diff line number Diff line Loading @@ -24,7 +24,9 @@ import android.app.Dialog; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.credentials.CredentialManager; import android.credentials.CredentialProviderInfo; import android.credentials.SetEnabledProvidersException; Loading @@ -32,6 +34,7 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.OutcomeReceiver; import android.os.UserHandle; import android.text.TextUtils; import android.util.IconDrawableFactory; import android.util.Log; Loading Loading @@ -162,10 +165,54 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl PreferenceGroup group = screen.findPreference(getPreferenceKey()); Context context = screen.getContext(); mPrefs.putAll(buildPreferenceList(context, group)); } for (CredentialProviderInfo service : mServices) { group.addPreference(createPreference(context, service)); /** Aggregates the list of services and builds a list of UI prefs to show. */ @VisibleForTesting public Map<String, SwitchPreference> buildPreferenceList( Context context, PreferenceGroup group) { // Group the services by package name. Map<String, List<CredentialProviderInfo>> groupedInfos = new HashMap<>(); for (CredentialProviderInfo cpi : mServices) { String packageName = cpi.getServiceInfo().packageName; if (!groupedInfos.containsKey(packageName)) { groupedInfos.put(packageName, new ArrayList<>()); } groupedInfos.get(packageName).add(cpi); } // Build the pref list. Map<String, SwitchPreference> output = new HashMap<>(); for (String packageName : groupedInfos.keySet()) { List<CredentialProviderInfo> 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 don't show anything. if (TextUtils.isEmpty(title)) { continue; } // Build the pref and add it to the output & group. SwitchPreference pref = addProviderPreference(context, title, icon, packageName); output.put(packageName, pref); group.addPreference(pref); } return output; } /** Creates a preference object based on the provider info. */ Loading Loading @@ -238,7 +285,6 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl final SwitchPreference pref = new SwitchPreference(prefContext); pref.setTitle(title); pref.setChecked(mEnabledPackageNames.contains(packageName)); mPrefs.put(packageName, pref); if (icon != null) { pref.setIcon(Utils.getSafeIcon(icon)); Loading
tests/unit/src/com/android/settings/applications/credentials/CredentialManagerPreferenceControllerTest.java +89 −13 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import org.junit.runner.RunWith; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @RunWith(AndroidJUnit4.class) Loading @@ -55,6 +56,13 @@ public class CredentialManagerPreferenceControllerTest { private PreferenceScreen mScreen; private PreferenceCategory mCredentialsPreferenceCategory; private static final String TEST_PACKAGE_NAME_A = "com.android.providerA"; private static final String TEST_PACKAGE_NAME_B = "com.android.providerB"; private static final String TEST_PACKAGE_NAME_C = "com.android.providerC"; 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"; @Before public void setUp() { mContext = spy(ApplicationProvider.getApplicationContext()); Loading Loading @@ -114,10 +122,10 @@ public class CredentialManagerPreferenceControllerTest { @Test public void buildSwitchPreference() { CredentialProviderInfo providerInfo1 = createCredentialProviderInfo( createCredentialProviderInfoWithIsEnabled( "com.android.provider1", "ClassA", "Service Title", false); CredentialProviderInfo providerInfo2 = createCredentialProviderInfo( createCredentialProviderInfoWithIsEnabled( "com.android.provider2", "ClassA", "Service Title", false); CredentialManagerPreferenceController controller = createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2)); Loading Loading @@ -217,10 +225,10 @@ public class CredentialManagerPreferenceControllerTest { @Test public void handlesCredentialProviderInfoEnabledDisabled() { CredentialProviderInfo providerInfo1 = createCredentialProviderInfo( createCredentialProviderInfoWithIsEnabled( "com.android.provider1", "ClassA", "Service Title", false); CredentialProviderInfo providerInfo2 = createCredentialProviderInfo( createCredentialProviderInfoWithIsEnabled( "com.android.provider2", "ClassA", "Service Title", true); CredentialManagerPreferenceController controller = createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2)); Loading @@ -244,6 +252,63 @@ 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<String, SwitchPreference> prefs = controller.buildPreferenceList(mContext, mCredentialsPreferenceCategory); assertThat(prefs.size()).isEqualTo(3); assertThat(prefs.containsKey(TEST_PACKAGE_NAME_A)); 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)); 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)); assertThat(prefs.get(TEST_PACKAGE_NAME_C).getTitle()).isEqualTo(TEST_TITLE_SERVICE_C); assertThat(prefs.get(TEST_PACKAGE_NAME_C).isChecked()).isTrue(); } private CredentialManagerPreferenceController createControllerWithServices( List<CredentialProviderInfo> availableServices) { CredentialManagerPreferenceController controller = Loading @@ -259,23 +324,34 @@ public class CredentialManagerPreferenceControllerTest { private CredentialProviderInfo createCredentialProviderInfo( String packageName, String className) { return createCredentialProviderInfo(packageName, className, null, false); return createCredentialProviderInfoBuilder(packageName, className, null, "App Name") .build(); } private CredentialProviderInfo createCredentialProviderInfo( String packageName, String className, CharSequence label, boolean isEnabled) { private CredentialProviderInfo createCredentialProviderInfoWithIsEnabled( String packageName, String className, CharSequence serviceLabel, boolean isEnabled) { return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, "App Name") .setEnabled(isEnabled) .build(); } private CredentialProviderInfo createCredentialProviderInfoWithAppLabel( String packageName, String className, CharSequence serviceLabel, String appLabel) { return createCredentialProviderInfoBuilder(packageName, className, serviceLabel, appLabel) .build(); } private CredentialProviderInfo.Builder createCredentialProviderInfoBuilder( String packageName, String className, CharSequence serviceLabel, String appLabel) { ServiceInfo si = new ServiceInfo(); si.packageName = packageName; si.name = className; si.nonLocalizedLabel = "test"; si.nonLocalizedLabel = serviceLabel; si.applicationInfo = new ApplicationInfo(); si.applicationInfo.packageName = packageName; si.applicationInfo.nonLocalizedLabel = "test"; si.applicationInfo.nonLocalizedLabel = appLabel; return new CredentialProviderInfo.Builder(si) .setOverrideLabel(label) .setEnabled(isEnabled) .build(); return new CredentialProviderInfo.Builder(si).setOverrideLabel(serviceLabel); } }