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

Commit 16225e23 authored by Reema Bajwa's avatar Reema Bajwa
Browse files

Add provider facing CREATE APIs for Credential Manager.

Credential Manager is a set of APIs that allows developers to get and
create credentials. These credentials are sourced from providers that
are registered with the android framework.

Test: Built and Deployed on device locally.
Bug: 247545196
CTS-Coverage-Bug: 247549381

Change-Id: I640259d5c803260740633f489a8bcf3a4168b652
parent 9238ef21
Loading
Loading
Loading
Loading
+64 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 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.service.credentials;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.RemoteException;
import android.util.Log;

/**
 * Callback to be invoked as a response to {@link CreateCredentialRequest}.
 *
 * @hide
 */
public final class CreateCredentialCallback {
    private static final String TAG = "CreateCredentialCallback";

    private final ICreateCredentialCallback mCallback;

    /** @hide */
    public CreateCredentialCallback(@NonNull ICreateCredentialCallback callback) {
        mCallback = callback;
    }

    /**
     * Invoked on a successful response for {@link CreateCredentialRequest}
     * @param response The response from the credential provider.
     */
    public void onSuccess(@NonNull CreateCredentialResponse response) {
        try {
            mCallback.onSuccess(response);
        } catch (RemoteException e) {
            e.rethrowAsRuntimeException();
        }
    }

    /**
     * Invoked on a failure response for {@link CreateCredentialRequest}
     * @param errorCode The code defining the type of error.
     * @param message The message corresponding to the failure.
     */
    public void onFailure(int errorCode, @Nullable CharSequence message) {
        Log.w(TAG, "onFailure: " + message);
        try {
            mCallback.onFailure(errorCode, message);
        } catch (RemoteException e) {
            e.rethrowAsRuntimeException();
        }
    }
}
+3 −0
Original line number Diff line number Diff line
package android.service.credentials;

parcelable CreateCredentialRequest;
 No newline at end of file
+103 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 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.service.credentials;

import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;

import androidx.annotation.NonNull;

import com.android.internal.util.Preconditions;

import java.util.Objects;

/**
 * Request for creating a credential.
 *
 * @hide
 */
public final class CreateCredentialRequest implements Parcelable {
    private final @NonNull String mCallingPackage;
    private final @NonNull String mType;
    private final @NonNull Bundle mData;

    /**
     * Constructs a new instance.
     *
     * @throws IllegalArgumentException If {@code callingPackage}, or {@code type} string is
     * null or empty.
     * @throws NullPointerException If {@code data} is null.
     */
    public CreateCredentialRequest(@NonNull String callingPackage,
            @NonNull String type, @NonNull Bundle data) {
        mCallingPackage = Preconditions.checkStringNotEmpty(callingPackage,
                "callingPackage must not be null or empty");
        mType = Preconditions.checkStringNotEmpty(type,
                "type must not be null or empty");
        mData = Objects.requireNonNull(data, "data must not be null");
    }

    private CreateCredentialRequest(@NonNull Parcel in) {
        mCallingPackage = in.readString8();
        mType = in.readString8();
        mData = in.readBundle();
    }

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

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

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

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeString8(mCallingPackage);
        dest.writeString8(mType);
        dest.writeBundle(mData);
    }

    /** Returns the calling package of the calling app. */
    @NonNull
    public String getCallingPackage() {
        return mCallingPackage;
    }

    /** Returns the type of the credential to be created. */
    @NonNull
    public String getType() {
        return mType;
    }

    /** Returns the data to be used while creating the credential. */
    @NonNull
    public Bundle getData() {
        return mData;
    }
}
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 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.service.credentials;

parcelable CreateCredentialResponse;
+140 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 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.service.credentials;

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

import androidx.annotation.NonNull;

import com.android.internal.util.Preconditions;

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

/**
 * Response to a {@link CreateCredentialRequest}.
 *
 * @hide
 */
public final class CreateCredentialResponse implements Parcelable {
    private final @Nullable CharSequence mHeader;
    private final @NonNull List<SaveEntry> mSaveEntries;

    private CreateCredentialResponse(@NonNull Parcel in) {
        mHeader = in.readCharSequence();
        mSaveEntries = in.createTypedArrayList(SaveEntry.CREATOR);
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeCharSequence(mHeader);
        dest.writeTypedList(mSaveEntries);
    }

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

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

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

    /* package-private */ CreateCredentialResponse(
            @Nullable CharSequence header,
            @NonNull List<SaveEntry> saveEntries) {
        this.mHeader = header;
        this.mSaveEntries = saveEntries;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mSaveEntries);
    }

    /** Returns the header to be displayed on the UI. */
    public @Nullable CharSequence getHeader() {
        return mHeader;
    }

    /** Returns the list of save entries to be displayed on the UI. */
    public @NonNull List<SaveEntry> getSaveEntries() {
        return mSaveEntries;
    }

    /**
     * A builder for {@link CreateCredentialResponse}
     */
    @SuppressWarnings("WeakerAccess")
    public static final class Builder {

        private @Nullable CharSequence mHeader;
        private @NonNull List<SaveEntry> mSaveEntries = new ArrayList<>();

        /** Sets the header to be displayed on the UI. */
        public @NonNull Builder setHeader(@Nullable CharSequence header) {
            mHeader = header;
            return this;
        }

        /**
         * Sets the list of save entries to be shown on the UI.
         *
         * @throws IllegalArgumentException If {@code saveEntries} is empty.
         * @throws NullPointerException If {@code saveEntries} is null, or any of its elements
         * are null.
         */
        public @NonNull Builder setSaveEntries(@NonNull List<SaveEntry> saveEntries) {
            Preconditions.checkCollectionNotEmpty(saveEntries, "saveEntries");
            mSaveEntries = Preconditions.checkCollectionElementsNotNull(
                    saveEntries, "saveEntries");
            return this;
        }

        /**
         * Adds an entry to the list of save entries to be shown on the UI.
         *
         * @throws NullPointerException If {@code saveEntry} is null.
         */
        public @NonNull Builder addSaveEntry(@NonNull SaveEntry saveEntry) {
            mSaveEntries.add(Objects.requireNonNull(saveEntry));
            return this;
        }

        /**
         * Builds the instance.
         *
         * @throws IllegalArgumentException If {@code saveEntries} is empty.
         */
        public @NonNull CreateCredentialResponse build() {
            Preconditions.checkCollectionNotEmpty(mSaveEntries, "saveEntries must "
                    + "not be empty");
            return new CreateCredentialResponse(
                    mHeader,
                    mSaveEntries);
        }
    }
}
Loading