Add support for settingsActivity in settings

Adds support for apps to define settingsActivity
in their manifest which will be launched on tap
in CredMan settings.

Test: ondevice manual test
Bug: 300014059
Change-Id: I3c8879fc86cd9b90bed2a301afaa7d5b75e87e3d
This commit is contained in:
Becca Hughes
2023-09-29 09:26:40 -07:00
parent 2770170e0d
commit fa040ab39d

View File

@@ -96,6 +96,9 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
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 static final String SETTINGS_ACTIVITY_INTENT_ACTION = "android.intent.action.MAIN";
private static final String SETTINGS_ACTIVITY_INTENT_CATEGORY =
"android.intent.category.LAUNCHER";
private final PackageManager mPm;
private final IconDrawableFactory mIconFactory;
@@ -484,13 +487,22 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
continue;
}
// Get the settings activity.
CharSequence settingsActivity =
combinedInfo.getCredentialProviderInfos().get(0).getSettingsActivity();
Drawable icon = combinedInfo.getAppIcon(context, getUser());
CharSequence title = combinedInfo.getAppName(context);
// Build the pref and add it to the output & group.
CombiPreference pref =
addProviderPreference(
context, title, icon, packageName, combinedInfo.getSettingsSubtitle());
context,
title == null ? "" : title,
icon,
packageName,
combinedInfo.getSettingsSubtitle(),
settingsActivity);
output.put(packageName, pref);
group.addPreference(pref);
}
@@ -510,7 +522,8 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
label == null ? "" : label,
service.getServiceIcon(mContext),
service.getServiceInfo().packageName,
service.getSettingsSubtitle());
service.getSettingsSubtitle(),
service.getSettingsActivity());
}
/**
@@ -569,7 +582,8 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
@NonNull CharSequence title,
@Nullable Drawable icon,
@NonNull String packageName,
@Nullable CharSequence subtitle) {
@Nullable CharSequence subtitle,
@Nullable CharSequence settingsActivity) {
final CombiPreference pref =
new CombiPreference(prefContext, mEnabledPackageNames.contains(packageName));
pref.setTitle(title);
@@ -583,29 +597,73 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
}
pref.setPreferenceListener(
(p, isChecked) -> {
if (isChecked) {
if (mEnabledPackageNames.size() >= MAX_SELECTABLE_PROVIDERS) {
// Show the error if too many enabled.
pref.setChecked(false);
final DialogFragment fragment = newErrorDialogFragment();
new CombiPreference.OnCombiPreferenceClickListener() {
@Override
public void onCheckChanged(CombiPreference p, boolean isChecked) {
if (isChecked) {
if (mEnabledPackageNames.size() >= MAX_SELECTABLE_PROVIDERS) {
// Show the error if too many enabled.
pref.setChecked(false);
final DialogFragment fragment = newErrorDialogFragment();
if (fragment == null || mFragmentManager == null) {
if (fragment == null || mFragmentManager == null) {
return;
}
fragment.show(mFragmentManager, ErrorDialogFragment.TAG);
return;
}
fragment.show(mFragmentManager, ErrorDialogFragment.TAG);
togglePackageNameEnabled(packageName);
// Enable all prefs.
if (mPrefs.containsKey(packageName)) {
mPrefs.get(packageName).setChecked(true);
}
} else {
togglePackageNameDisabled(packageName);
}
}
@Override
public void onLeftSideClicked() {
if (settingsActivity == null) {
Log.w(TAG, "settingsActivity was null");
return;
}
togglePackageNameEnabled(packageName);
// Enable all prefs.
if (mPrefs.containsKey(packageName)) {
mPrefs.get(packageName).setChecked(true);
String settingsActivityStr = String.valueOf(settingsActivity);
ComponentName cn = ComponentName.unflattenFromString(settingsActivityStr);
if (cn == null) {
Log.w(
TAG,
"Failed to deserialize settingsActivity attribute, we got: "
+ settingsActivityStr);
return;
}
} else {
togglePackageNameDisabled(packageName);
Intent intent = new Intent(SETTINGS_ACTIVITY_INTENT_ACTION);
intent.addCategory(SETTINGS_ACTIVITY_INTENT_CATEGORY);
intent.setComponent(cn);
Context context = mContext;
int currentUserId = getUser();
int contextUserId = context.getUser().getIdentifier();
if (currentUserId != contextUserId) {
Log.d(
TAG,
"onLeftSideClicked(): using context for current user ("
+ currentUserId
+ ") instead of user "
+ contextUserId
+ " on headless system user mode");
context =
context.createContextAsUser(
UserHandle.of(currentUserId), /* flags= */ 0);
}
context.startActivity(intent);
}
});
@@ -921,6 +979,9 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
public interface OnCombiPreferenceClickListener {
/** Called when the check is updated */
void onCheckChanged(CombiPreference p, boolean isChecked);
/** Called when the left side is clicked. */
void onLeftSideClicked();
}
public CombiPreference(Context context, boolean initialValue) {
@@ -969,6 +1030,18 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
// Store this for later.
mSwitch = switchView;
}
super.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (mOnClickListener != null) {
mOnClickListener.onLeftSideClicked();
}
return true;
}
});
}
}
}