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

Commit 85ec2063 authored by Helen Qin's avatar Helen Qin Committed by Android (Google) Code Review
Browse files

Merge "Define the UI result code and corresponding data structures."

parents 60a827fa 2b2e8343
Loading
Loading
Loading
Loading
+123 −0
Original line number 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.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.util.AnnotationValidations;

/**
 * Base dialog result data.
 *
 * Returned for simple use cases like cancellation. Can also be subclassed when more information
 * is needed, e.g. {@link UserSelectionDialogResult}.
 *
 * @hide
 */
public class BaseDialogResult implements Parcelable {
    /** Parses and returns a BaseDialogResult from the given resultData. */
    @Nullable
    public static BaseDialogResult fromResultData(@NonNull Bundle resultData) {
        return resultData.getParcelable(EXTRA_BASE_RESULT, BaseDialogResult.class);
    }

    /**
     * Used for the UX to construct the {@code resultData Bundle} to send via the {@code
     *  ResultReceiver}.
     */
    public static void addToBundle(@NonNull BaseDialogResult result, @NonNull Bundle bundle) {
        bundle.putParcelable(EXTRA_BASE_RESULT, result);
    }

    /**
     * The intent extra key for the {@code BaseDialogResult} object when the credential
     * selector activity finishes.
     */
    private static final String EXTRA_BASE_RESULT =
            "android.credentials.ui.extra.BASE_RESULT";

    /** User intentionally canceled the dialog. */
    public static final int RESULT_CODE_DIALOG_CANCELED = 0;
    /**
     * User made a selection and the dialog finished. The user selection result is in the
     * {@code resultData}.
     */
    public static final int RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION = 1;
    /**
     * The user has acknowledged the consent page rendered for when they first used Credential
     * Manager on this device.
     */
    public static final int RESULT_CODE_CREDENTIAL_MANAGER_CONSENT_ACKNOWLEDGED = 2;
    /**
     * The user has acknowledged the consent page rendered for enabling a new provider.
     * This should only happen during the first time use. The provider info is in the
     * {@code resultData}.
     */
    public static final int RESULT_CODE_PROVIDER_ENABLED = 3;
    /**
     * The user has consented to switching to a new default provider. The provider info is in the
     * {@code resultData}.
     */
    public static final int RESULT_CODE_DEFAULT_PROVIDER_CHANGED = 4;

    @NonNull
    private final IBinder mRequestToken;

    public BaseDialogResult(@NonNull IBinder requestToken) {
        mRequestToken = requestToken;
    }

    /** Returns the unique identifier for the request that launched the operation. */
    @NonNull
    public IBinder getRequestToken() {
        return mRequestToken;
    }

    protected BaseDialogResult(@NonNull Parcel in) {
        IBinder requestToken = in.readStrongBinder();
        mRequestToken = requestToken;
        AnnotationValidations.validate(NonNull.class, null, mRequestToken);
    }

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

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

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

        @Override
        public BaseDialogResult[] newArray(int size) {
            return new BaseDialogResult[size];
        }
    };
}
+100 −0
Original line number 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.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.util.AnnotationValidations;

/**
 * Result data matching {@link BaseDialogResult#RESULT_CODE_PROVIDER_ENABLED}, or {@link
 * BaseDialogResult#RESULT_CODE_DEFAULT_PROVIDER_CHANGED}.
 *
 * @hide
 */
public class ProviderDialogResult extends BaseDialogResult implements Parcelable {
    /** Parses and returns a ProviderDialogResult from the given resultData. */
    @Nullable
    public static ProviderDialogResult fromResultData(@NonNull Bundle resultData) {
        return resultData.getParcelable(EXTRA_PROVIDER_RESULT, ProviderDialogResult.class);
    }

    /**
     * Used for the UX to construct the {@code resultData Bundle} to send via the {@code
     *  ResultReceiver}.
     */
    public static void addToBundle(
            @NonNull ProviderDialogResult result, @NonNull Bundle bundle) {
        bundle.putParcelable(EXTRA_PROVIDER_RESULT, result);
    }

    /**
     * The intent extra key for the {@code ProviderDialogResult} object when the credential
     * selector activity finishes.
     */
    private static final String EXTRA_PROVIDER_RESULT =
            "android.credentials.ui.extra.PROVIDER_RESULT";

    @NonNull
    private final String mProviderId;

    public ProviderDialogResult(@NonNull IBinder requestToken, @NonNull String providerId) {
        super(requestToken);
        mProviderId = providerId;
    }

    @NonNull
    public String getProviderId() {
        return mProviderId;
    }

    protected ProviderDialogResult(@NonNull Parcel in) {
        super(in);
        String providerId = in.readString8();
        mProviderId = providerId;
        AnnotationValidations.validate(NonNull.class, null, mProviderId);
    }

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

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

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

        @Override
        public ProviderDialogResult[] newArray(int size) {
            return new ProviderDialogResult[size];
        }
    };
}
+35 −31
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package android.credentials.ui;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -24,24 +26,33 @@ import android.os.Parcelable;
import com.android.internal.util.AnnotationValidations;

/**
 * User selection result information of a UX flow.
 *
 * Returned as part of the activity result intent data when the user dialog completes
 * successfully.
 * Result data matching {@link BaseDialogResult#RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION}.
 *
 * @hide
 */
public class UserSelectionResult implements Parcelable {
public class UserSelectionDialogResult extends BaseDialogResult implements Parcelable {
    /** Parses and returns a UserSelectionDialogResult from the given resultData. */
    @Nullable
    public static UserSelectionDialogResult fromResultData(@NonNull Bundle resultData) {
        return resultData.getParcelable(
            EXTRA_USER_SELECTION_RESULT, UserSelectionDialogResult.class);
    }

    /**
    * The intent extra key for the {@code UserSelectionResult} object when the credential selector
    * activity finishes.
     * Used for the UX to construct the {@code resultData Bundle} to send via the {@code
     *  ResultReceiver}.
     */
    public static final String EXTRA_USER_SELECTION_RESULT =
            "android.credentials.ui.extra.USER_SELECTION_RESULT";
    public static void addToBundle(
            @NonNull UserSelectionDialogResult result, @NonNull Bundle bundle) {
        bundle.putParcelable(EXTRA_USER_SELECTION_RESULT, result);
    }

    @NonNull
    private final IBinder mRequestToken;
    /**
     * The intent extra key for the {@code UserSelectionDialogResult} object when the credential
     * selector activity finishes.
     */
    private static final String EXTRA_USER_SELECTION_RESULT =
            "android.credentials.ui.extra.USER_SELECTION_RESULT";

    @NonNull
    private final String mProviderId;
@@ -49,19 +60,14 @@ public class UserSelectionResult implements Parcelable {
    // TODO: consider switching to string or other types, depending on the service implementation.
    private final int mEntryId;

    public UserSelectionResult(@NonNull IBinder requestToken, @NonNull String providerId,
    public UserSelectionDialogResult(
            @NonNull IBinder requestToken, @NonNull String providerId,
            int entryId) {
        mRequestToken = requestToken;
        super(requestToken);
        mProviderId = providerId;
        mEntryId = entryId;
    }

    /** Returns token of the app request that initiated this user dialog. */
    @NonNull
    public IBinder getRequestToken() {
        return mRequestToken;
    }

    /** Returns provider package name whose entry was selected by the user. */
    @NonNull
    public String getProviderId() {
@@ -73,13 +79,11 @@ public class UserSelectionResult implements Parcelable {
        return mEntryId;
    }

    protected UserSelectionResult(@NonNull Parcel in) {
        IBinder requestToken = in.readStrongBinder();
    protected UserSelectionDialogResult(@NonNull Parcel in) {
        super(in);
        String providerId = in.readString8();
        int entryId = in.readInt();

        mRequestToken = requestToken;
        AnnotationValidations.validate(NonNull.class, null, mRequestToken);
        mProviderId = providerId;
        AnnotationValidations.validate(NonNull.class, null, mProviderId);
        mEntryId = entryId;
@@ -87,7 +91,7 @@ public class UserSelectionResult implements Parcelable {

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeStrongBinder(mRequestToken);
        super.writeToParcel(dest, flags);
        dest.writeString8(mProviderId);
        dest.writeInt(mEntryId);
    }
@@ -97,16 +101,16 @@ public class UserSelectionResult implements Parcelable {
        return 0;
    }

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

        @Override
        public UserSelectionResult[] newArray(int size) {
            return new UserSelectionResult[size];
        public UserSelectionDialogResult[] newArray(int size) {
            return new UserSelectionDialogResult[size];
        }
    };
}
+8 −9
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.credentialmanager

import android.app.Activity
import android.app.slice.Slice
import android.app.slice.SliceSpec
import android.content.Context
@@ -25,7 +24,8 @@ import android.credentials.ui.Constants
import android.credentials.ui.Entry
import android.credentials.ui.ProviderData
import android.credentials.ui.RequestInfo
import android.credentials.ui.UserSelectionResult
import android.credentials.ui.BaseDialogResult
import android.credentials.ui.UserSelectionDialogResult
import android.graphics.drawable.Icon
import android.os.Binder
import android.os.Bundle
@@ -68,21 +68,20 @@ class CredentialManagerRepo(
  }

  fun onCancel() {
    resultReceiver?.send(Activity.RESULT_CANCELED, null)
    val resultData = Bundle()
    BaseDialogResult.addToBundle(BaseDialogResult(requestInfo.token), resultData)
    resultReceiver?.send(BaseDialogResult.RESULT_CODE_DIALOG_CANCELED, resultData)
  }

  fun onOptionSelected(providerPackageName: String, entryId: Int) {
    val userSelectionResult = UserSelectionResult(
    val userSelectionDialogResult = UserSelectionDialogResult(
      requestInfo.token,
      providerPackageName,
      entryId
    )
    val resultData = Bundle()
    resultData.putParcelable(
      UserSelectionResult.EXTRA_USER_SELECTION_RESULT,
      userSelectionResult
    )
    resultReceiver?.send(Activity.RESULT_OK, resultData)
    UserSelectionDialogResult.addToBundle(userSelectionDialogResult, resultData)
    resultReceiver?.send(BaseDialogResult.RESULT_CODE_DIALOG_COMPLETE_WITH_SELECTION, resultData)
  }

  fun getCredentialInitialUiState(): GetCredentialUiState {