Merge "Merge credential manager providers by package name" into udc-dev am: e87159a591

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/21964743

Change-Id: I309fb2ec5a9c26b682cf1086d753ee2d60bc79b4
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
TreeHugger Robot
2023-03-14 23:23:32 +00:00
committed by Automerger Merge Worker
2 changed files with 143 additions and 21 deletions

View File

@@ -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;
@@ -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;
@@ -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. */
@@ -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));

View File

@@ -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)
@@ -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());
@@ -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));
@@ -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));
@@ -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 =
@@ -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) {
ServiceInfo si = new ServiceInfo();
si.packageName = packageName;
si.name = className;
si.nonLocalizedLabel = "test";
si.applicationInfo = new ApplicationInfo();
si.applicationInfo.packageName = packageName;
si.applicationInfo.nonLocalizedLabel = "test";
return new CredentialProviderInfo.Builder(si)
.setOverrideLabel(label)
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 = serviceLabel;
si.applicationInfo = new ApplicationInfo();
si.applicationInfo.packageName = packageName;
si.applicationInfo.nonLocalizedLabel = appLabel;
return new CredentialProviderInfo.Builder(si).setOverrideLabel(serviceLabel);
}
}