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: 573e844275)
Merged-In: Ief25f562eb5c2ca4438701de8a8e26941a8370a3
This commit is contained in:
Becca Hughes
2023-03-06 18:59:15 +00:00
committed by Cherrypicker Worker
parent e4058d20a7
commit e174f66a71
2 changed files with 116 additions and 65 deletions

View File

@@ -25,14 +25,11 @@ import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.credentials.CredentialManager; import android.credentials.CredentialManager;
import android.credentials.ListEnabledProvidersException; import android.credentials.CredentialProviderInfo;
import android.credentials.ListEnabledProvidersResponse;
import android.credentials.SetEnabledProvidersException; import android.credentials.SetEnabledProvidersException;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.OutcomeReceiver; import android.os.OutcomeReceiver;
import android.os.UserHandle; import android.os.UserHandle;
import android.util.IconDrawableFactory; import android.util.IconDrawableFactory;
@@ -71,10 +68,9 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
private final PackageManager mPm; private final PackageManager mPm;
private final IconDrawableFactory mIconFactory; private final IconDrawableFactory mIconFactory;
private final List<ServiceInfo> mServices; private final List<CredentialProviderInfo> mServices;
private final Set<String> mEnabledPackageNames; private final Set<String> mEnabledPackageNames;
private final @Nullable CredentialManager mCredentialManager; private final @Nullable CredentialManager mCredentialManager;
private final CancellationSignal mCancellationSignal = new CancellationSignal();
private final Executor mExecutor; private final Executor mExecutor;
private final Map<String, SwitchPreference> mPrefs = new HashMap<>(); // key is package name private final Map<String, SwitchPreference> mPrefs = new HashMap<>(); // key is package name
@@ -132,42 +128,20 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
lifecycleOwner, lifecycleOwner,
mCredentialManager.getCredentialProviderServices( mCredentialManager.getCredentialProviderServices(
getUser(), CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY)); getUser(), CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY));
mCredentialManager.listEnabledProviders(
mCancellationSignal,
mExecutor,
new OutcomeReceiver<ListEnabledProvidersResponse, ListEnabledProvidersException>() {
@Override
public void onResult(ListEnabledProvidersResponse result) {
Set<String> 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 @VisibleForTesting
void setAvailableServices(LifecycleOwner lifecycleOwner, List<ServiceInfo> availableServices) { void setAvailableServices(
LifecycleOwner lifecycleOwner, List<CredentialProviderInfo> availableServices) {
mServices.clear(); mServices.clear();
mServices.addAll(availableServices); mServices.addAll(availableServices);
}
@VisibleForTesting
void setEnabledPackageNames(Set<String> enabledPackages) {
mEnabledPackageNames.clear(); mEnabledPackageNames.clear();
mEnabledPackageNames.addAll(enabledPackages); for (CredentialProviderInfo cpi : availableServices) {
if (cpi.isEnabled()) {
mEnabledPackageNames.add(cpi.getServiceInfo().packageName);
}
}
for (String packageName : mPrefs.keySet()) { for (String packageName : mPrefs.keySet()) {
mPrefs.get(packageName).setChecked(mEnabledPackageNames.contains(packageName)); mPrefs.get(packageName).setChecked(mEnabledPackageNames.contains(packageName));
@@ -189,22 +163,22 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
PreferenceGroup group = screen.findPreference(getPreferenceKey()); PreferenceGroup group = screen.findPreference(getPreferenceKey());
Context context = screen.getContext(); Context context = screen.getContext();
for (ServiceInfo serviceInfo : mServices) { for (CredentialProviderInfo service : mServices) {
CharSequence title = ""; group.addPreference(createPreference(context, service));
if (serviceInfo.nonLocalizedLabel != null) {
title = serviceInfo.loadLabel(mPm);
}
group.addPreference(
addProviderPreference(
context,
title,
mIconFactory.getBadgedIcon(
serviceInfo, serviceInfo.applicationInfo, getUser()),
serviceInfo.packageName));
} }
} }
/** 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. * Enables the package name as an enabled credential manager provider.
* *
@@ -246,9 +220,10 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
public List<String> getEnabledSettings() { public List<String> getEnabledSettings() {
// Get all the component names that match the enabled package names. // Get all the component names that match the enabled package names.
List<String> enabledServices = new ArrayList<>(); List<String> enabledServices = new ArrayList<>();
for (ServiceInfo service : mServices) { for (CredentialProviderInfo service : mServices) {
if (mEnabledPackageNames.contains(service.packageName)) { ComponentName cn = service.getServiceInfo().getComponentName();
enabledServices.add(service.getComponentName().flattenToString()); if (mEnabledPackageNames.contains(service.getServiceInfo().packageName)) {
enabledServices.add(cn.flattenToString());
} }
} }

View File

@@ -27,12 +27,14 @@ import static org.mockito.Mockito.spy;
import android.content.Context; import android.content.Context;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.ServiceInfo; import android.content.pm.ServiceInfo;
import android.credentials.CredentialProviderInfo;
import android.os.Looper; import android.os.Looper;
import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -87,7 +89,7 @@ public class CredentialManagerPreferenceControllerTest {
@Test @Test
public void getAvailabilityStatus_withServices_returnsAvailable() { public void getAvailabilityStatus_withServices_returnsAvailable() {
CredentialManagerPreferenceController controller = CredentialManagerPreferenceController controller =
createControllerWithServices(Lists.newArrayList(createServiceInfo())); createControllerWithServices(Lists.newArrayList(createCredentialProviderInfo()));
assertThat(controller.isConnected()).isFalse(); assertThat(controller.isConnected()).isFalse();
assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE); assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
} }
@@ -103,24 +105,59 @@ public class CredentialManagerPreferenceControllerTest {
@Test @Test
public void displayPreference_withServices_preferencesAdded() { public void displayPreference_withServices_preferencesAdded() {
CredentialManagerPreferenceController controller = CredentialManagerPreferenceController controller =
createControllerWithServices(Lists.newArrayList(createServiceInfo())); createControllerWithServices(Lists.newArrayList(createCredentialProviderInfo()));
controller.displayPreference(mScreen); controller.displayPreference(mScreen);
assertThat(controller.isConnected()).isFalse(); assertThat(controller.isConnected()).isFalse();
assertThat(mCredentialsPreferenceCategory.getPreferenceCount()).isEqualTo(1); 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<String> 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 @Test
public void getAvailabilityStatus_handlesToggleAndSave() { public void getAvailabilityStatus_handlesToggleAndSave() {
CredentialManagerPreferenceController controller = CredentialManagerPreferenceController controller =
createControllerWithServices( createControllerWithServices(
Lists.newArrayList( Lists.newArrayList(
createServiceInfo("com.android.provider1", "ClassA"), createCredentialProviderInfo("com.android.provider1", "ClassA"),
createServiceInfo("com.android.provider1", "ClassB"), createCredentialProviderInfo("com.android.provider1", "ClassB"),
createServiceInfo("com.android.provider2", "ClassA"), createCredentialProviderInfo("com.android.provider2", "ClassA"),
createServiceInfo("com.android.provider3", "ClassA"), createCredentialProviderInfo("com.android.provider3", "ClassA"),
createServiceInfo("com.android.provider4", "ClassA"), createCredentialProviderInfo("com.android.provider4", "ClassA"),
createServiceInfo("com.android.provider5", "ClassA"), createCredentialProviderInfo("com.android.provider5", "ClassA"),
createServiceInfo("com.android.provider6", "ClassA"))); createCredentialProviderInfo("com.android.provider6", "ClassA")));
assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE); assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
assertThat(controller.isConnected()).isFalse(); assertThat(controller.isConnected()).isFalse();
@@ -177,8 +214,38 @@ public class CredentialManagerPreferenceControllerTest {
assertThat(currentlyEnabledServices.contains("com.android.provider6/ClassA")).isFalse(); 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<String> 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<String> 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( private CredentialManagerPreferenceController createControllerWithServices(
List<ServiceInfo> availableServices) { List<CredentialProviderInfo> availableServices) {
CredentialManagerPreferenceController controller = CredentialManagerPreferenceController controller =
new CredentialManagerPreferenceController( new CredentialManagerPreferenceController(
mContext, mCredentialsPreferenceCategory.getKey()); mContext, mCredentialsPreferenceCategory.getKey());
@@ -186,11 +253,17 @@ public class CredentialManagerPreferenceControllerTest {
return controller; return controller;
} }
private ServiceInfo createServiceInfo() { private CredentialProviderInfo createCredentialProviderInfo() {
return createServiceInfo("com.android.provider", "CredManProvider"); 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(); ServiceInfo si = new ServiceInfo();
si.packageName = packageName; si.packageName = packageName;
si.name = className; si.name = className;
@@ -200,6 +273,9 @@ public class CredentialManagerPreferenceControllerTest {
si.applicationInfo.packageName = packageName; si.applicationInfo.packageName = packageName;
si.applicationInfo.nonLocalizedLabel = "test"; si.applicationInfo.nonLocalizedLabel = "test";
return si; return new CredentialProviderInfo.Builder(si)
.setOverrideLabel(label)
.setEnabled(isEnabled)
.build();
} }
} }