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

Commit 1a0805dd authored by Helen Qin's avatar Helen Qin
Browse files

Modify the UI interface according to new product decisions.

Also split up the ProviderData into type specific subclasses: one for
get, one for create, and one for disabled providers.

Test: local deployment
Bug: 247855226
Bug: 253156958
Change-Id: I453e615c30a150dc2d3cf987c1affa7a9f4f9356
parent 1c897f2c
Loading
Loading
Loading
Loading
+164 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.credentials.ui;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.util.AnnotationValidations;

import java.util.ArrayList;
import java.util.List;

/**
 * Per-provider metadata and entries for the create-credential flow.
 *
 * @hide
 */
public class CreateCredentialProviderData extends ProviderData implements Parcelable {
    @NonNull
    private final List<Entry> mSaveEntries;
    @NonNull
    private final List<Entry> mActionChips;
    private final boolean mIsDefaultProvider;
    @Nullable
    private final Entry mRemoteEntry;

    public CreateCredentialProviderData(
            @NonNull String providerFlattenedComponentName, @NonNull List<Entry> saveEntries,
            @NonNull List<Entry> actionChips, boolean isDefaultProvider,
            @Nullable Entry remoteEntry) {
        super(providerFlattenedComponentName);
        mSaveEntries = saveEntries;
        mActionChips = actionChips;
        mIsDefaultProvider = isDefaultProvider;
        mRemoteEntry = remoteEntry;
    }

    @NonNull
    public List<Entry> getSaveEntries() {
        return mSaveEntries;
    }

    @NonNull
    public List<Entry> getActionChips() {
        return mActionChips;
    }

    public boolean isDefaultProvider() {
        return mIsDefaultProvider;
    }

    @Nullable
    public Entry getRemoteEntry() {
        return mRemoteEntry;
    }

    protected CreateCredentialProviderData(@NonNull Parcel in) {
        super(in);

        List<Entry> credentialEntries = new ArrayList<>();
        in.readTypedList(credentialEntries, Entry.CREATOR);
        mSaveEntries = credentialEntries;
        AnnotationValidations.validate(NonNull.class, null, mSaveEntries);

        List<Entry> actionChips  = new ArrayList<>();
        in.readTypedList(actionChips, Entry.CREATOR);
        mActionChips = actionChips;
        AnnotationValidations.validate(NonNull.class, null, mActionChips);

        mIsDefaultProvider = in.readBoolean();

        Entry remoteEntry = in.readTypedObject(Entry.CREATOR);
        mRemoteEntry = remoteEntry;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeTypedList(mSaveEntries);
        dest.writeTypedList(mActionChips);
        dest.writeBoolean(isDefaultProvider());
        dest.writeTypedObject(mRemoteEntry, flags);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final @NonNull Creator<CreateCredentialProviderData> CREATOR =
            new Creator<CreateCredentialProviderData>() {
        @Override
        public CreateCredentialProviderData createFromParcel(@NonNull Parcel in) {
            return new CreateCredentialProviderData(in);
        }

        @Override
        public CreateCredentialProviderData[] newArray(int size) {
            return new CreateCredentialProviderData[size];
        }
    };

    /**
     * Builder for {@link CreateCredentialProviderData}.
     *
     * @hide
     */
    public static class Builder {
        private @NonNull String mProviderFlattenedComponentName;
        private @NonNull List<Entry> mSaveEntries = new ArrayList<>();
        private @NonNull List<Entry> mActionChips = new ArrayList<>();
        private boolean mIsDefaultProvider = false;
        private @Nullable Entry mRemoteEntry = null;

        /** Constructor with required properties. */
        public Builder(@NonNull String providerFlattenedComponentName) {
            mProviderFlattenedComponentName = providerFlattenedComponentName;
        }

        /** Sets the list of save credential entries to be displayed to the user. */
        @NonNull
        public Builder setSaveEntries(@NonNull List<Entry> credentialEntries) {
            mSaveEntries = credentialEntries;
            return this;
        }

        /** Sets the list of action chips to be displayed to the user. */
        @NonNull
        public Builder setActionChips(@NonNull List<Entry> actionChips) {
            mActionChips = actionChips;
            return this;
        }

        /** Sets whether this provider is the user's selected default provider. */
        @NonNull
        public Builder setIsDefaultProvider(boolean isDefaultProvider) {
            mIsDefaultProvider = isDefaultProvider;
            return this;
        }

        /** Builds a {@link CreateCredentialProviderData}. */
        @NonNull
        public CreateCredentialProviderData build() {
            return new CreateCredentialProviderData(mProviderFlattenedComponentName,
                    mSaveEntries, mActionChips, mIsDefaultProvider, mRemoteEntry);
        }
    }
}
+60 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.credentials.ui;

import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * Metadata of a disabled provider.
 *
 * @hide
 */
public class DisabledProviderData extends ProviderData implements Parcelable {

    public DisabledProviderData(
            @NonNull String providerFlattenedComponentName) {
        super(providerFlattenedComponentName);
    }

    protected DisabledProviderData(@NonNull Parcel in) {
        super(in);
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final @NonNull Creator<DisabledProviderData> CREATOR = new Creator<>() {
                @Override
                public DisabledProviderData createFromParcel(@NonNull Parcel in) {
                    return new DisabledProviderData(in);
                }

                @Override
                public DisabledProviderData[] newArray(int size) {
                    return new DisabledProviderData[size];
                }
    };
}
+174 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.credentials.ui;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.util.AnnotationValidations;

import java.util.ArrayList;
import java.util.List;

/**
 * Per-provider metadata and entries for the get-credential flow.
 *
 * @hide
 */
public class GetCredentialProviderData extends ProviderData implements Parcelable {
    @NonNull
    private final List<Entry> mCredentialEntries;
    @NonNull
    private final List<Entry> mActionChips;
    @Nullable
    private final Entry mAuthenticationEntry;
    @Nullable
    private final Entry mRemoteEntry;

    public GetCredentialProviderData(
            @NonNull String providerFlattenedComponentName, @NonNull List<Entry> credentialEntries,
            @NonNull List<Entry> actionChips, @Nullable Entry authenticationEntry,
            @Nullable Entry remoteEntry) {
        super(providerFlattenedComponentName);
        mCredentialEntries = credentialEntries;
        mActionChips = actionChips;
        mAuthenticationEntry = authenticationEntry;
        mRemoteEntry = remoteEntry;
    }

    @NonNull
    public List<Entry> getCredentialEntries() {
        return mCredentialEntries;
    }

    @NonNull
    public List<Entry> getActionChips() {
        return mActionChips;
    }

    @Nullable
    public Entry getAuthenticationEntry() {
        return mAuthenticationEntry;
    }

    @Nullable
    public Entry getRemoteEntry() {
        return mRemoteEntry;
    }

    protected GetCredentialProviderData(@NonNull Parcel in) {
        super(in);

        List<Entry> credentialEntries = new ArrayList<>();
        in.readTypedList(credentialEntries, Entry.CREATOR);
        mCredentialEntries = credentialEntries;
        AnnotationValidations.validate(NonNull.class, null, mCredentialEntries);

        List<Entry> actionChips  = new ArrayList<>();
        in.readTypedList(actionChips, Entry.CREATOR);
        mActionChips = actionChips;
        AnnotationValidations.validate(NonNull.class, null, mActionChips);

        Entry authenticationEntry = in.readTypedObject(Entry.CREATOR);
        mAuthenticationEntry = authenticationEntry;

        Entry remoteEntry = in.readTypedObject(Entry.CREATOR);
        mRemoteEntry = remoteEntry;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeTypedList(mCredentialEntries);
        dest.writeTypedList(mActionChips);
        dest.writeTypedObject(mAuthenticationEntry, flags);
        dest.writeTypedObject(mRemoteEntry, flags);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final @NonNull Creator<GetCredentialProviderData> CREATOR =
            new Creator<GetCredentialProviderData>() {
        @Override
        public GetCredentialProviderData createFromParcel(@NonNull Parcel in) {
            return new GetCredentialProviderData(in);
        }

        @Override
        public GetCredentialProviderData[] newArray(int size) {
            return new GetCredentialProviderData[size];
        }
    };

    /**
     * Builder for {@link GetCredentialProviderData}.
     *
     * @hide
     */
    public static class Builder {
        private @NonNull String mProviderFlattenedComponentName;
        private @NonNull List<Entry> mCredentialEntries = new ArrayList<>();
        private @NonNull List<Entry> mActionChips = new ArrayList<>();
        private @Nullable Entry mAuthenticationEntry = null;
        private @Nullable Entry mRemoteEntry = null;

        /** Constructor with required properties. */
        public Builder(@NonNull String providerFlattenedComponentName) {
            mProviderFlattenedComponentName = providerFlattenedComponentName;
        }

        /** Sets the list of save / get credential entries to be displayed to the user. */
        @NonNull
        public Builder setCredentialEntries(@NonNull List<Entry> credentialEntries) {
            mCredentialEntries = credentialEntries;
            return this;
        }

        /** Sets the list of action chips to be displayed to the user. */
        @NonNull
        public Builder setActionChips(@NonNull List<Entry> actionChips) {
            mActionChips = actionChips;
            return this;
        }

        /** Sets the authentication entry to be displayed to the user. */
        @NonNull
        public Builder setAuthenticationEntry(@Nullable Entry authenticationEntry) {
            mAuthenticationEntry = authenticationEntry;
            return this;
        }

        /** Sets the remote entry to be displayed to the user. */
        @NonNull
        public Builder setRemoteEntry(@Nullable Entry remoteEntry) {
            mRemoteEntry = remoteEntry;
            return this;
        }

        /** Builds a {@link GetCredentialProviderData}. */
        @NonNull
        public GetCredentialProviderData build() {
            return new GetCredentialProviderData(mProviderFlattenedComponentName,
                    mCredentialEntries, mActionChips, mAuthenticationEntry, mRemoteEntry);
        }
    }
}
+8 −3
Original line number Original line Diff line number Diff line
@@ -30,15 +30,20 @@ import java.util.ArrayList;
 */
 */
public class IntentFactory {
public class IntentFactory {
    /** Generate a new launch intent to the . */
    /** Generate a new launch intent to the . */
    public static Intent newIntent(RequestInfo requestInfo,
    public static Intent newIntent(
            ArrayList<ProviderData> providerDataList, ResultReceiver resultReceiver) {
            RequestInfo requestInfo,
            ArrayList<ProviderData> enabledProviderDataList,
            ArrayList<DisabledProviderData> disabledProviderDataList,
            ResultReceiver resultReceiver) {
        Intent intent = new Intent();
        Intent intent = new Intent();
        // TODO: define these as proper config strings.
        // TODO: define these as proper config strings.
        String activityName = "com.android.credentialmanager/.CredentialSelectorActivity";
        String activityName = "com.android.credentialmanager/.CredentialSelectorActivity";
        intent.setComponent(ComponentName.unflattenFromString(activityName));
        intent.setComponent(ComponentName.unflattenFromString(activityName));


        intent.putParcelableArrayListExtra(
        intent.putParcelableArrayListExtra(
                ProviderData.EXTRA_PROVIDER_DATA_LIST, providerDataList);
                ProviderData.EXTRA_ENABLED_PROVIDER_DATA_LIST, enabledProviderDataList);
        intent.putParcelableArrayListExtra(
                ProviderData.EXTRA_DISABLED_PROVIDER_DATA_LIST, disabledProviderDataList);
        intent.putExtra(RequestInfo.EXTRA_REQUEST_INFO, requestInfo);
        intent.putExtra(RequestInfo.EXTRA_REQUEST_INFO, requestInfo);
        intent.putExtra(Constants.EXTRA_RESULT_RECEIVER,
        intent.putExtra(Constants.EXTRA_RESULT_RECEIVER,
                toIpcFriendlyResultReceiver(resultReceiver));
                toIpcFriendlyResultReceiver(resultReceiver));
+17 −187
Original line number Original line Diff line number Diff line
@@ -16,232 +16,62 @@


package android.credentials.ui;
package android.credentials.ui;


import android.annotation.CurrentTimeMillisLong;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.drawable.Icon;
import android.os.Parcel;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable;


import com.android.internal.util.AnnotationValidations;
import com.android.internal.util.AnnotationValidations;


import java.util.ArrayList;
import java.util.List;

/**
/**
 * Holds metadata and credential entries for a single provider.
 * Super class for data structures that hold metadata and credential entries for a single provider.
 *
 *
 * @hide
 * @hide
 */
 */
public class ProviderData implements Parcelable {
public abstract class ProviderData implements Parcelable {


    /**
    /**
     * The intent extra key for the list of {@code ProviderData} when launching the UX
     * The intent extra key for the list of {@code ProviderData} from active providers when
     * activities.
     * launching the UX activities.
     */
    public static final String EXTRA_ENABLED_PROVIDER_DATA_LIST =
            "android.credentials.ui.extra.ENABLED_PROVIDER_DATA_LIST";
    /**
     * The intent extra key for the list of {@code ProviderData} from disabled providers when
     * launching the UX activities.
     */
     */
    public static final String EXTRA_PROVIDER_DATA_LIST =
    public static final String EXTRA_DISABLED_PROVIDER_DATA_LIST =
            "android.credentials.ui.extra.PROVIDER_DATA_LIST";
            "android.credentials.ui.extra.DISABLED_PROVIDER_DATA_LIST";


    @NonNull
    @NonNull
    private final String mProviderFlattenedComponentName;
    private final String mProviderFlattenedComponentName;
    @NonNull
    private final String mProviderDisplayName;
    @Nullable
    private final Icon mIcon;
    @NonNull
    private final List<Entry> mCredentialEntries;
    @NonNull
    private final List<Entry> mActionChips;
    @Nullable
    private final Entry mAuthenticationEntry;

    private final @CurrentTimeMillisLong long mLastUsedTimeMillis;


    public ProviderData(
    public ProviderData(
            @NonNull String providerFlattenedComponentName, @NonNull String providerDisplayName,
            @NonNull String providerFlattenedComponentName) {
            @Nullable Icon icon, @NonNull List<Entry> credentialEntries,
            @NonNull List<Entry> actionChips, @Nullable Entry authenticationEntry,
            @CurrentTimeMillisLong long lastUsedTimeMillis) {
        mProviderFlattenedComponentName = providerFlattenedComponentName;
        mProviderFlattenedComponentName = providerFlattenedComponentName;
        mProviderDisplayName = providerDisplayName;
        mIcon = icon;
        mCredentialEntries = credentialEntries;
        mActionChips = actionChips;
        mAuthenticationEntry = authenticationEntry;
        mLastUsedTimeMillis = lastUsedTimeMillis;
    }
    }


    /** Returns the unique provider id. */
    /**
     * Returns provider component name.
     * It also serves as the unique identifier for this provider.
     */
    @NonNull
    @NonNull
    public String getProviderFlattenedComponentName() {
    public String getProviderFlattenedComponentName() {
        return mProviderFlattenedComponentName;
        return mProviderFlattenedComponentName;
    }
    }


    @NonNull
    public String getProviderDisplayName() {
        return mProviderDisplayName;
    }

    @Nullable
    public Icon getIcon() {
        return mIcon;
    }

    @NonNull
    public List<Entry> getCredentialEntries() {
        return mCredentialEntries;
    }

    @NonNull
    public List<Entry> getActionChips() {
        return mActionChips;
    }

    @Nullable
    public Entry getAuthenticationEntry() {
        return mAuthenticationEntry;
    }

    /** Returns the time when the provider was last used. */
    public @CurrentTimeMillisLong long getLastUsedTimeMillis() {
        return mLastUsedTimeMillis;
    }

    protected ProviderData(@NonNull Parcel in) {
    protected ProviderData(@NonNull Parcel in) {
        String providerFlattenedComponentName = in.readString8();
        String providerFlattenedComponentName = in.readString8();
        mProviderFlattenedComponentName = providerFlattenedComponentName;
        mProviderFlattenedComponentName = providerFlattenedComponentName;
        AnnotationValidations.validate(NonNull.class, null, mProviderFlattenedComponentName);
        AnnotationValidations.validate(NonNull.class, null, mProviderFlattenedComponentName);

        String providerDisplayName = in.readString8();
        mProviderDisplayName = providerDisplayName;
        AnnotationValidations.validate(NonNull.class, null, mProviderDisplayName);

        Icon icon = in.readTypedObject(Icon.CREATOR);
        mIcon = icon;

        List<Entry> credentialEntries = new ArrayList<>();
        in.readTypedList(credentialEntries, Entry.CREATOR);
        mCredentialEntries = credentialEntries;
        AnnotationValidations.validate(NonNull.class, null, mCredentialEntries);

        List<Entry> actionChips  = new ArrayList<>();
        in.readTypedList(actionChips, Entry.CREATOR);
        mActionChips = actionChips;
        AnnotationValidations.validate(NonNull.class, null, mActionChips);

        Entry authenticationEntry = in.readTypedObject(Entry.CREATOR);
        mAuthenticationEntry = authenticationEntry;

        long lastUsedTimeMillis = in.readLong();
        mLastUsedTimeMillis = lastUsedTimeMillis;
    }
    }


    @Override
    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeString8(mProviderFlattenedComponentName);
        dest.writeString8(mProviderFlattenedComponentName);
        dest.writeString8(mProviderDisplayName);
        dest.writeTypedObject(mIcon, flags);
        dest.writeTypedList(mCredentialEntries);
        dest.writeTypedList(mActionChips);
        dest.writeTypedObject(mAuthenticationEntry, flags);
        dest.writeLong(mLastUsedTimeMillis);
    }
    }


    @Override
    @Override
    public int describeContents() {
    public int describeContents() {
        return 0;
        return 0;
    }
    }

    public static final @NonNull Creator<ProviderData> CREATOR = new Creator<ProviderData>() {
        @Override
        public ProviderData createFromParcel(@NonNull Parcel in) {
            return new ProviderData(in);
        }

        @Override
        public ProviderData[] newArray(int size) {
            return new ProviderData[size];
        }
    };

    /**
     * Builder for {@link ProviderData}.
     *
     * @hide
     */
    public static class Builder {
        private @NonNull String mProviderFlattenedComponentName;
        private @NonNull String mProviderDisplayName;
        private @Nullable Icon mIcon;
        private @NonNull List<Entry> mCredentialEntries = new ArrayList<>();
        private @NonNull List<Entry> mActionChips = new ArrayList<>();
        private @Nullable Entry mAuthenticationEntry = null;
        private @CurrentTimeMillisLong long mLastUsedTimeMillis = 0L;

        /** Constructor with required properties. */
        public Builder(@NonNull String providerFlattenedComponentName,
                @NonNull String providerDisplayName,
                @Nullable Icon icon) {
            mProviderFlattenedComponentName = providerFlattenedComponentName;
            mProviderDisplayName = providerDisplayName;
            mIcon = icon;
        }

        /** Sets the unique provider id. */
        @NonNull
        public Builder setProviderFlattenedComponentName(@NonNull String providerFlattenedComponentName) {
            mProviderFlattenedComponentName = providerFlattenedComponentName;
            return this;
        }

        /** Sets the provider display name to be displayed to the user. */
        @NonNull
        public Builder setProviderDisplayName(@NonNull String providerDisplayName) {
            mProviderDisplayName = providerDisplayName;
            return this;
        }

        /** Sets the provider icon to be displayed to the user. */
        @NonNull
        public Builder setIcon(@NonNull Icon icon) {
            mIcon = icon;
            return this;
        }

        /** Sets the list of save / get credential entries to be displayed to the user. */
        @NonNull
        public Builder setCredentialEntries(@NonNull List<Entry> credentialEntries) {
            mCredentialEntries = credentialEntries;
            return this;
        }

        /** Sets the list of action chips to be displayed to the user. */
        @NonNull
        public Builder setActionChips(@NonNull List<Entry> actionChips) {
            mActionChips = actionChips;
            return this;
        }

        /** Sets the authentication entry to be displayed to the user. */
        @NonNull
        public Builder setAuthenticationEntry(@Nullable Entry authenticationEntry) {
            mAuthenticationEntry = authenticationEntry;
            return this;
        }

        /** Sets the time when the provider was last used. */
        @NonNull
        public Builder setLastUsedTimeMillis(@CurrentTimeMillisLong long lastUsedTimeMillis) {
            mLastUsedTimeMillis = lastUsedTimeMillis;
            return this;
        }

        /** Builds a {@link ProviderData}. */
        @NonNull
        public ProviderData build() {
            return new ProviderData(mProviderFlattenedComponentName, mProviderDisplayName,
                    mIcon, mCredentialEntries,
                mActionChips, mAuthenticationEntry, mLastUsedTimeMillis);
        }
    }
}
}
Loading