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

Commit aa1b7e44 authored by Reema Bajwa's avatar Reema Bajwa
Browse files

Add request to authentication entry pending intent

Test: Built & deployed locally
Bug: 264943831

Change-Id: I76f5fc493c5ad6960c19f3b80429dd45b4c4840f
parent a4597637
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -39938,6 +39938,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