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

Commit 8b0fad3c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add request to authentication entry pending intent"

parents 88a21f8e aa1b7e44
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -39948,6 +39948,7 @@ package android.service.credentials {
    method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
    method public abstract void onClearCredentialState(@NonNull android.service.credentials.ClearCredentialStateRequest, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.credentials.ClearCredentialStateException>);
    field public static final String CAPABILITY_META_DATA_KEY = "android.credentials.capabilities";
    field public static final String EXTRA_BEGIN_GET_CREDENTIAL_REQUEST = "android.service.credentials.extra.BEGIN_GET_CREDENTIAL_REQUEST";
    field public static final String EXTRA_CREATE_CREDENTIAL_EXCEPTION = "android.service.credentials.extra.CREATE_CREDENTIAL_EXCEPTION";
    field public static final String EXTRA_CREATE_CREDENTIAL_REQUEST = "android.service.credentials.extra.CREATE_CREDENTIAL_REQUEST";
    field public static final String EXTRA_CREATE_CREDENTIAL_RESPONSE = "android.service.credentials.extra.CREATE_CREDENTIAL_RESPONSE";
+1 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ public final class Entry implements Parcelable {
    /** Constructor to be used for an entry that requires a pending intent to be invoked
     * when clicked.
     */
    // TODO: Remove this constructor as it is no longer used
    public Entry(@NonNull String key, @NonNull String subkey, @NonNull Slice slice,
            @NonNull PendingIntent pendingIntent, @NonNull Intent intent) {
        this(key, subkey, slice);
+27 −0
Original line number Diff line number Diff line
@@ -125,6 +125,33 @@ public abstract class CredentialProviderService extends Service {
    public static final String EXTRA_CREATE_CREDENTIAL_EXCEPTION =
            "android.service.credentials.extra.CREATE_CREDENTIAL_EXCEPTION";

    /**
     * Intent extra: The {@link BeginGetCredentialRequest} attached with
     * the {@code pendingIntent} that is invoked when the user selects an
     * authentication entry (intending to unlock the provider app) on the UI.
     *
     * <p>When a provider app receives a {@link BeginGetCredentialRequest} through the
     * {@link CredentialProviderService#onBeginGetCredential} call, it can construct the
     * {@link BeginGetCredentialResponse} with either an authentication {@link Action} (if the app
     * is locked), or a {@link CredentialsResponseContent} (if the app is unlocked). In the former
     * case, i.e. the app is locked, user will be shown the authentication action. When selected,
     * the underlying {@link PendingIntent} will be invoked which will lead the user to provider's
     * unlock activity. This pending intent will also contain the original
     * {@link BeginGetCredentialRequest} to be retrieved and processed after the unlock
     * flow is complete.
     *
     * <p>After the app is unlocked, the {@link BeginGetCredentialResponse} must be constructed
     * using a {@link CredentialsResponseContent}, which must be set on an {@link Intent} as an
     * intent extra against CredentialProviderService#EXTRA_CREDENTIALS_RESPONSE_CONTENT}.
     * This intent should then be set as a result through {@link android.app.Activity#setResult}
     * before finishing the activity.
     *
     * <p>
     * Type: {@link BeginGetCredentialRequest}
     */
    public static final String EXTRA_BEGIN_GET_CREDENTIAL_REQUEST =
            "android.service.credentials.extra.BEGIN_GET_CREDENTIAL_REQUEST";

    private static final String TAG = "CredProviderService";

    public static final String CAPABILITY_META_DATA_KEY = "android.credentials.capabilities";
+8 −3
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import com.android.credentialmanager.jetpack.developer.CreatePasswordRequest
import com.android.credentialmanager.jetpack.developer.CreatePublicKeyCredentialRequest
import com.android.credentialmanager.jetpack.developer.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
import com.android.credentialmanager.jetpack.provider.Action
import com.android.credentialmanager.jetpack.provider.AuthenticationAction
import com.android.credentialmanager.jetpack.provider.CredentialCountInformation
import com.android.credentialmanager.jetpack.provider.CredentialEntry
import com.android.credentialmanager.jetpack.provider.CreateEntry
@@ -140,16 +141,20 @@ class GetFlowUtils {
            providerIcon: Drawable,
            authEntry: Entry?,
    ): AuthenticationEntryInfo? {
      // TODO: should also call fromSlice after getting the official jetpack code.

      if (authEntry == null) {
        return null
      }
      val authStructuredEntry = AuthenticationAction.fromSlice(
              authEntry!!.slice)
      if (authStructuredEntry == null) {
        return null
      }

      return AuthenticationEntryInfo(
              providerId = providerId,
              entryKey = authEntry.key,
              entrySubkey = authEntry.subkey,
              pendingIntent = authEntry.pendingIntent,
              pendingIntent = authStructuredEntry.pendingIntent,
              fillInIntent = authEntry.frameworkExtrasIntent,
              title = providerDisplayName,
              icon = providerIcon,
+55 −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 com.android.credentialmanager.jetpack.provider

import android.app.PendingIntent
import android.app.slice.Slice
import android.util.Log
import androidx.annotation.VisibleForTesting

/**
 * UI representation for a credential entry used during the get credential flow.
 *
 * TODO: move to jetpack.
 */
class AuthenticationAction constructor(
        val pendingIntent: PendingIntent
) {


  companion object {
    private const val TAG = "AuthenticationAction"
    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    internal const val SLICE_HINT_PENDING_INTENT =
            "androidx.credentials.provider.authenticationAction.SLICE_HINT_PENDING_INTENT"

    @JvmStatic
    fun fromSlice(slice: Slice): AuthenticationAction? {
      slice.items.forEach {
        if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {
          return try {
            AuthenticationAction(it.action)
          } catch (e: Exception) {
            Log.i(TAG, "fromSlice failed with: " + e.message)
            null
          }
        }
      }
      return null
    }
  }
}
Loading