Add single provider and single account screens

Bug: 301206470
Test: N/A - feature not fully implemented yet

Change-Id: I25f54e2bcb8228b46a8ca7a89f63753c639a26ef
diff --git a/packages/CredentialManager/shared/Android.bp b/packages/CredentialManager/shared/Android.bp
index ae4281e..38d98a9 100644
--- a/packages/CredentialManager/shared/Android.bp
+++ b/packages/CredentialManager/shared/Android.bp
@@ -14,5 +14,6 @@
     static_libs: [
         "androidx.core_core-ktx",
         "androidx.credentials_credentials",
+        "guava",
     ],
 }
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt
index 6627af5..43d8fb3 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/IntentParser.kt
@@ -17,11 +17,15 @@
 package com.android.credentialmanager.ui
 
 import android.content.Intent
+import android.credentials.ui.GetCredentialProviderData
 import android.credentials.ui.RequestInfo
 import com.android.credentialmanager.ui.ktx.cancelUiRequest
+import com.android.credentialmanager.ui.ktx.getCredentialProviderDataList
 import com.android.credentialmanager.ui.ktx.requestInfo
 import com.android.credentialmanager.ui.mapper.toCancel
 import com.android.credentialmanager.ui.model.Request
+import com.google.common.collect.ImmutableList
+import com.google.common.collect.ImmutableMap
 
 fun Intent.parse(): Request {
     cancelUiRequest?.let {
@@ -32,9 +36,23 @@
         RequestInfo.TYPE_CREATE -> {
             Request.Create
         }
+
         RequestInfo.TYPE_GET -> {
-            Request.Get
+            Request.Get(
+                providers = ImmutableMap.copyOf(
+                    getCredentialProviderDataList.associateBy { it.providerFlattenedComponentName }
+                ),
+                entries = ImmutableList.copyOf(
+                    getCredentialProviderDataList.map { providerData ->
+                        check(providerData is GetCredentialProviderData) {
+                            "Invalid provider data type for GetCredentialRequest"
+                        }
+                        providerData
+                    }.flatMap { it.credentialEntries }
+                )
+            )
         }
+
         else -> {
             throw IllegalStateException("Unrecognized request type: ${requestInfo?.type}")
         }
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/factory/CredentialEntryFactory.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/factory/CredentialEntryFactory.kt
new file mode 100644
index 0000000..f01fded
--- /dev/null
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/factory/CredentialEntryFactory.kt
@@ -0,0 +1,25 @@
+package com.android.credentialmanager.ui.factory
+
+import android.app.slice.Slice
+import android.credentials.Credential
+import androidx.credentials.PublicKeyCredential
+import androidx.credentials.provider.CredentialEntry
+import androidx.credentials.provider.CustomCredentialEntry
+import androidx.credentials.provider.PasswordCredentialEntry
+import androidx.credentials.provider.PublicKeyCredentialEntry
+
+fun fromSlice(slice: Slice): CredentialEntry? =
+    try {
+        when (slice.spec?.type) {
+            Credential.TYPE_PASSWORD_CREDENTIAL -> PasswordCredentialEntry.fromSlice(slice)!!
+
+            PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
+                PublicKeyCredentialEntry.fromSlice(slice)!!
+
+            else -> CustomCredentialEntry.fromSlice(slice)!!
+        }
+    } catch (e: Exception) {
+        // Try CustomCredentialEntry.fromSlice one last time in case the cause was a failed
+        // password / passkey parsing attempt.
+        CustomCredentialEntry.fromSlice(slice)
+    }
\ No newline at end of file
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt
index a646851..b9895a0 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/ktx/IntentKtx.kt
@@ -18,6 +18,9 @@
 
 import android.content.Intent
 import android.credentials.ui.CancelUiRequest
+import android.credentials.ui.CreateCredentialProviderData
+import android.credentials.ui.GetCredentialProviderData
+import android.credentials.ui.ProviderData
 import android.credentials.ui.RequestInfo
 
 val Intent.cancelUiRequest: CancelUiRequest?
@@ -30,4 +33,16 @@
     get() = this.extras?.getParcelable(
         RequestInfo.EXTRA_REQUEST_INFO,
         RequestInfo::class.java
-    )
\ No newline at end of file
+    )
+
+val Intent.getCredentialProviderDataList: List<ProviderData>
+    get() = this.extras?.getParcelableArrayList(
+        ProviderData.EXTRA_ENABLED_PROVIDER_DATA_LIST,
+        GetCredentialProviderData::class.java
+    ) ?: emptyList()
+
+val Intent.createCredentialProviderDataList: List<ProviderData>
+    get() = this.extras?.getParcelableArrayList(
+        ProviderData.EXTRA_ENABLED_PROVIDER_DATA_LIST,
+        CreateCredentialProviderData::class.java
+    ) ?: emptyList()
diff --git a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt
index 3d835be..cffa2b2 100644
--- a/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt
+++ b/packages/CredentialManager/shared/src/com/android/credentialmanager/ui/model/Request.kt
@@ -16,6 +16,11 @@
 
 package com.android.credentialmanager.ui.model
 
+import android.credentials.ui.Entry
+import android.credentials.ui.ProviderData
+import com.google.common.collect.ImmutableList
+import com.google.common.collect.ImmutableMap
+
 /**
  * Represents the request made by the CredentialManager API.
  */
@@ -25,7 +30,10 @@
         val appPackageName: String?
     ) : Request()
 
-    data object Get : Request()
+    data class Get(
+        val providers: ImmutableMap<String, ProviderData>,
+        val entries: ImmutableList<Entry>,
+    ) : Request()
 
     data object Create : Request()
 }