diff options
| author | 2024-02-03 05:51:24 +0000 | |
|---|---|---|
| committer | 2024-02-03 05:51:24 +0000 | |
| commit | f1a1d17489af779e15be05a047c1fdf50e9e8b68 (patch) | |
| tree | 9354e02b38e5b15f58fb2d0587f84c6744d77ac0 | |
| parent | 71de38a812f5e6a2f154a59e4f8ce0437da44940 (diff) | |
| parent | 889629ffe270a4674afe9fdac0db185601b04280 (diff) | |
Merge "Read and use the oem CredMan UI override." into main
3 files changed, 92 insertions, 11 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 9f739aee9c71..a21d7c464bf6 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1333,7 +1333,7 @@ package android.credentials.selection { @FlaggedApi("android.credentials.flags.configurable_selector_ui_enabled") public class IntentFactory { method @NonNull public static android.content.Intent createCancelUiIntent(@NonNull android.os.IBinder, boolean, @NonNull String); - method @NonNull public static android.content.Intent createCredentialSelectorIntent(@NonNull android.credentials.selection.RequestInfo, @NonNull java.util.ArrayList<android.credentials.selection.ProviderData>, @NonNull java.util.ArrayList<android.credentials.selection.DisabledProviderData>, @NonNull android.os.ResultReceiver); + method @NonNull public static android.content.Intent createCredentialSelectorIntent(@NonNull android.content.Context, @NonNull android.credentials.selection.RequestInfo, @NonNull java.util.ArrayList<android.credentials.selection.ProviderData>, @NonNull java.util.ArrayList<android.credentials.selection.DisabledProviderData>, @NonNull android.os.ResultReceiver); } @FlaggedApi("android.credentials.flags.configurable_selector_ui_enabled") public abstract class ProviderData implements android.os.Parcelable { diff --git a/core/java/android/credentials/selection/IntentFactory.java b/core/java/android/credentials/selection/IntentFactory.java index f03a00d7070d..1837976f5d1f 100644 --- a/core/java/android/credentials/selection/IntentFactory.java +++ b/core/java/android/credentials/selection/IntentFactory.java @@ -17,6 +17,7 @@ package android.credentials.selection; import static android.credentials.flags.Flags.FLAG_CONFIGURABLE_SELECTOR_UI_ENABLED; +import static android.credentials.flags.Flags.configurableSelectorUiEnabled; import android.annotation.FlaggedApi; import android.annotation.NonNull; @@ -24,11 +25,16 @@ import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.TestApi; import android.content.ComponentName; +import android.content.Context; import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.os.IBinder; import android.os.Parcel; import android.os.ResultReceiver; +import android.text.TextUtils; +import android.util.Slog; import java.util.ArrayList; @@ -42,12 +48,14 @@ import java.util.ArrayList; public class IntentFactory { /** - * Generate a new launch intent to the Credential Selector UI. + * Generate a new launch intent to the Credential Selector UI for auto-filling. * * @hide */ @NonNull + // TODO(b/323552850) - clean up method overloads public static Intent createCredentialSelectorIntent( + @NonNull Context context, @NonNull RequestInfo requestInfo, @SuppressLint("ConcreteCollection") // Concrete collection needed for marshalling. @Nullable @@ -60,10 +68,10 @@ public class IntentFactory { Intent intent; if (enabledProviderDataList != null) { - intent = createCredentialSelectorIntent(requestInfo, enabledProviderDataList, + intent = createCredentialSelectorIntent(context, requestInfo, enabledProviderDataList, disabledProviderDataList, resultReceiver); } else { - intent = createCredentialSelectorIntent(requestInfo, + intent = createCredentialSelectorIntent(context, requestInfo, disabledProviderDataList, resultReceiver); } intent.putExtra(Constants.EXTRA_REQ_FOR_ALL_OPTIONS, isRequestForAllOptions); @@ -77,7 +85,8 @@ public class IntentFactory { * @hide */ @NonNull - public static Intent createCredentialSelectorIntent( + private static Intent createCredentialSelectorIntent( + @NonNull Context context, @NonNull RequestInfo requestInfo, @SuppressLint("ConcreteCollection") // Concrete collection needed for marshalling. @NonNull @@ -90,6 +99,10 @@ public class IntentFactory { .getString( com.android.internal.R.string .config_credentialManagerDialogComponent)); + ComponentName oemOverrideComponentName = getOemOverrideComponentName(context); + if (oemOverrideComponentName != null) { + componentName = oemOverrideComponentName; + } intent.setComponent(componentName); intent.putParcelableArrayListExtra( ProviderData.EXTRA_DISABLED_PROVIDER_DATA_LIST, disabledProviderDataList); @@ -100,9 +113,73 @@ public class IntentFactory { return intent; } - /** Generate a new launch intent to the Credential Selector UI. */ + /** + * Returns null if there is not an enabled and valid oem override component. It means the + * default platform UI component name should be used instead. + */ + @Nullable + private static ComponentName getOemOverrideComponentName(@NonNull Context context) { + ComponentName result = null; + if (configurableSelectorUiEnabled()) { + if (Resources.getSystem().getBoolean( + com.android.internal.R.bool.config_enableOemCredentialManagerDialogComponent)) { + String oemComponentString = + Resources.getSystem() + .getString( + com.android.internal.R.string + .config_oemCredentialManagerDialogComponent); + if (!TextUtils.isEmpty(oemComponentString)) { + ComponentName oemComponentName = ComponentName.unflattenFromString( + oemComponentString); + if (oemComponentName != null) { + try { + ActivityInfo info = context.getPackageManager().getActivityInfo( + oemComponentName, + PackageManager.ComponentInfoFlags.of( + PackageManager.MATCH_SYSTEM_ONLY)); + if (info.enabled && info.exported) { + Slog.i(TAG, + "Found enabled oem CredMan UI component." + + oemComponentString); + result = oemComponentName; + } else { + Slog.i(TAG, + "Found enabled oem CredMan UI component but it was not " + + "enabled."); + } + } catch (PackageManager.NameNotFoundException e) { + Slog.i(TAG, "Unable to find oem CredMan UI component: " + + oemComponentString + "."); + } + } else { + Slog.i(TAG, "Invalid OEM ComponentName format."); + } + } else { + Slog.i(TAG, "Invalid empty OEM component name."); + } + } + } + return result; + } + + /** + * Generate a new launch intent to the Credential Selector UI. + * + * @param context the CredentialManager system service (only expected caller) + * context that may be used to query existence of the key UI + * application + * @param disabledProviderDataList the list of disabled provider data that when non-empty the + * UI should accordingly generate an entry suggesting the user + * to navigate to settings and enable them + * @param enabledProviderDataList the list of enabled provider that contain options for this + * request; the UI should render each option to the user for + * selection + * @param requestInfo the display information about the given app request + * @param resultReceiver used by the UI to send the UI selection result back + */ @NonNull public static Intent createCredentialSelectorIntent( + @NonNull Context context, @NonNull RequestInfo requestInfo, @SuppressLint("ConcreteCollection") // Concrete collection needed for marshalling. @NonNull @@ -111,7 +188,7 @@ public class IntentFactory { @NonNull ArrayList<DisabledProviderData> disabledProviderDataList, @NonNull ResultReceiver resultReceiver) { - Intent intent = createCredentialSelectorIntent(requestInfo, + Intent intent = createCredentialSelectorIntent(context, requestInfo, disabledProviderDataList, resultReceiver); intent.putParcelableArrayListExtra( ProviderData.EXTRA_ENABLED_PROVIDER_DATA_LIST, enabledProviderDataList); @@ -153,5 +230,8 @@ public class IntentFactory { return ipcFriendly; } - private IntentFactory() {} + private IntentFactory() { + } + + private static final String TAG = "CredManIntentHelper"; } diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java index e8b32cd5d805..84b5cb785a41 100644 --- a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java +++ b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java @@ -148,8 +148,8 @@ public class CredentialManagerUi { * Creates a {@link PendingIntent} to be used to invoke the credential manager selector UI, * by the calling app process. * - * @param requestInfo the information about the request - * @param providerDataList the list of provider data from remote providers + * @param requestInfo the information about the request + * @param providerDataList the list of provider data from remote providers * @param isRequestForAllOptions whether the bottom sheet should directly navigate to the * all options page */ @@ -170,7 +170,8 @@ public class CredentialManagerUi { .map(disabledProvider -> new DisabledProviderData( disabledProvider.getComponentName().flattenToString())).toList(); - Intent intent = IntentFactory.createCredentialSelectorIntent(requestInfo, providerDataList, + Intent intent = IntentFactory.createCredentialSelectorIntent(mContext, requestInfo, + providerDataList, new ArrayList<>(disabledProviderDataList), mResultReceiver, isRequestForAllOptions) .setAction(UUID.randomUUID().toString()); |