Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9efcb17a authored by Becca Hughes's avatar Becca Hughes Committed by Android (Google) Code Review
Browse files

Merge "Add settingsActivity API to Credential Manager" into main

parents de0f94ef 1cc2b680
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1181,6 +1181,7 @@ package android.credentials {
    method @Nullable public CharSequence getLabel(@NonNull android.content.Context);
    method @Nullable public android.graphics.drawable.Drawable getServiceIcon(@NonNull android.content.Context);
    method @NonNull public android.content.pm.ServiceInfo getServiceInfo();
    method @FlaggedApi("android.credentials.flags.settings_activity_enabled") @Nullable public CharSequence getSettingsActivity();
    method @Nullable public CharSequence getSettingsSubtitle();
    method @NonNull public boolean hasCapability(@NonNull String);
    method public boolean isEnabled();
+33 −4
Original line number Diff line number Diff line
@@ -16,12 +16,14 @@

package android.credentials;

import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ServiceInfo;
import android.credentials.flags.Flags;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -42,6 +44,7 @@ public final class CredentialProviderInfo implements Parcelable {
    @NonNull private final List<String> mCapabilities = new ArrayList<>();
    @Nullable private final CharSequence mOverrideLabel;
    @Nullable private CharSequence mSettingsSubtitle = null;
    @Nullable private CharSequence mSettingsActivity = null;
    private final boolean mIsSystemProvider;
    private final boolean mIsEnabled;
    private final boolean mIsPrimary;
@@ -59,6 +62,7 @@ public final class CredentialProviderInfo implements Parcelable {
        mIsEnabled = builder.mIsEnabled;
        mIsPrimary = builder.mIsPrimary;
        mOverrideLabel = builder.mOverrideLabel;
        mSettingsActivity = builder.mSettingsActivity;
    }

    /** Returns true if the service supports the given {@code credentialType}, false otherwise. */
@@ -104,10 +108,7 @@ public final class CredentialProviderInfo implements Parcelable {
        return mIsEnabled;
    }

    /**
     * Returns whether the provider is set as primary by the user.
     *
     */
    /** Returns whether the provider is set as primary by the user. */
    public boolean isPrimary() {
        return mIsPrimary;
    }
@@ -118,6 +119,18 @@ public final class CredentialProviderInfo implements Parcelable {
        return mSettingsSubtitle;
    }

    /**
     * Returns the settings activity.
     *
     * @hide
     */
    @Nullable
    @TestApi
    @FlaggedApi(Flags.FLAG_SETTINGS_ACTIVITY_ENABLED)
    public CharSequence getSettingsActivity() {
        return mSettingsActivity;
    }

    /** Returns the component name for the service. */
    @NonNull
    public ComponentName getComponentName() {
@@ -133,6 +146,7 @@ public final class CredentialProviderInfo implements Parcelable {
        dest.writeBoolean(mIsPrimary);
        TextUtils.writeToParcel(mOverrideLabel, dest, flags);
        TextUtils.writeToParcel(mSettingsSubtitle, dest, flags);
        TextUtils.writeToParcel(mSettingsActivity, dest, flags);
    }

    @Override
@@ -161,6 +175,9 @@ public final class CredentialProviderInfo implements Parcelable {
                + "settingsSubtitle="
                + mSettingsSubtitle
                + ", "
                + "settingsActivity="
                + mSettingsActivity
                + ", "
                + "capabilities="
                + String.join(",", mCapabilities)
                + "}";
@@ -174,6 +191,7 @@ public final class CredentialProviderInfo implements Parcelable {
        mIsPrimary = in.readBoolean();
        mOverrideLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
        mSettingsSubtitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
        mSettingsActivity = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
    }

    public static final @NonNull Parcelable.Creator<CredentialProviderInfo> CREATOR =
@@ -196,6 +214,7 @@ public final class CredentialProviderInfo implements Parcelable {
        @NonNull private List<String> mCapabilities = new ArrayList<>();
        private boolean mIsSystemProvider = false;
        @Nullable private CharSequence mSettingsSubtitle = null;
        @Nullable private CharSequence mSettingsActivity = null;
        private boolean mIsEnabled = false;
        private boolean mIsPrimary = false;
        @Nullable private CharSequence mOverrideLabel = null;
@@ -231,6 +250,16 @@ public final class CredentialProviderInfo implements Parcelable {
            return this;
        }

        /**
         * Sets the settings activity.
         *
         * @hide
         */
        public @NonNull Builder setSettingsActivity(@Nullable CharSequence settingsActivity) {
            mSettingsActivity = settingsActivity;
            return this;
        }

        /** Sets a list of capabilities this provider service can support. */
        public @NonNull Builder addCapabilities(@NonNull List<String> capabilities) {
            mCapabilities.addAll(capabilities);
+26 −6
Original line number Diff line number Diff line
@@ -45,8 +45,8 @@ import android.util.AttributeSet;
import android.util.Slog;
import android.util.Xml;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -135,8 +135,8 @@ public final class CredentialProviderInfoFactory {
    }

    /**
     * Constructs an information instance of the credential provider for testing purposes. Does
     * not run any verifications and passes parameters as is.
     * Constructs an information instance of the credential provider for testing purposes. Does not
     * run any verifications and passes parameters as is.
     */
    @VisibleForTesting
    public static CredentialProviderInfo createForTests(
@@ -151,7 +151,6 @@ public final class CredentialProviderInfoFactory {
                .setSystemProvider(isSystemProvider)
                .addCapabilities(capabilities)
                .build();

    }

    private static void verifyProviderPermission(ServiceInfo serviceInfo) throws SecurityException {
@@ -267,15 +266,21 @@ public final class CredentialProviderInfoFactory {
                                    allAttributes,
                                    com.android.internal.R.styleable.CredentialProvider);
                    builder.setSettingsSubtitle(
                            afsAttributes.getString(
                            getAfsAttributeSafe(
                                    afsAttributes,
                                    R.styleable.CredentialProvider_settingsSubtitle));
                    builder.setSettingsActivity(
                            getAfsAttributeSafe(
                                    afsAttributes,
                                    R.styleable.CredentialProvider_settingsActivity));
                } catch (Exception e) {
                    Slog.e(TAG, "Failed to get XML attr", e);
                    Slog.w(TAG, "Failed to get XML attr for metadata", e);
                } finally {
                    if (afsAttributes != null) {
                        afsAttributes.recycle();
                    }
                }

                builder.addCapabilities(parseXmlProviderOuterCapabilities(parser, resources));
            } else {
                Slog.w(TAG, "Meta-data does not start with credential-provider-service tag");
@@ -287,6 +292,21 @@ public final class CredentialProviderInfoFactory {
        return builder;
    }

    private static @Nullable String getAfsAttributeSafe(
            @Nullable TypedArray afsAttributes, int resId) {
        if (afsAttributes == null) {
            return null;
        }

        try {
            return afsAttributes.getString(resId);
        } catch (Exception e) {
            Slog.w(TAG, "Failed to get XML attr from afs attributes", e);
        }

        return null;
    }

    private static List<String> parseXmlProviderOuterCapabilities(
            XmlPullParser parser, Resources resources) throws IOException, XmlPullParserException {
        final List<String> capabilities = new ArrayList<>();
+3 −0
Original line number Diff line number Diff line
@@ -10118,6 +10118,9 @@
             screen that can be used to provide more information about a provider. For
             longer strings it will be truncated. -->
        <attr name="settingsSubtitle" format="string" />
        <!-- Fully qualified class name of an activity that allows the user to modify
             the settings for this service. -->
        <attr name="settingsActivity" />
    </declare-styleable>
    <!-- A list of capabilities that indicates to the OS what kinds of credentials