blob: 1e43d541ac13161b915cafcbf31ba6b057fe5891 [file] [log] [blame]
/*
* 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
import android.content.Context
import android.content.pm.PackageManager
import android.credentials.ui.Entry
import android.credentials.ui.GetCredentialProviderData
import android.credentials.ui.CreateCredentialProviderData
import android.credentials.ui.DisabledProviderData
import com.android.credentialmanager.createflow.CreateOptionInfo
import com.android.credentialmanager.createflow.RemoteInfo
import com.android.credentialmanager.getflow.ActionEntryInfo
import com.android.credentialmanager.getflow.AuthenticationEntryInfo
import com.android.credentialmanager.getflow.CredentialEntryInfo
import com.android.credentialmanager.getflow.ProviderInfo
import com.android.credentialmanager.jetpack.provider.CredentialEntryUi
import com.android.credentialmanager.jetpack.provider.SaveEntryUi
/** Utility functions for converting CredentialManager data structures to or from UI formats. */
class GetFlowUtils {
companion object {
fun toProviderList(
providerDataList: List<GetCredentialProviderData>,
context: Context,
): List<ProviderInfo> {
return providerDataList.map {
ProviderInfo(
id = it.providerFlattenedComponentName,
// TODO: replace to extract from the service data structure when available
icon = context.getDrawable(R.drawable.ic_passkey)!!,
// TODO: get the service display name and icon from the component name.
displayName = it.providerFlattenedComponentName,
credentialEntryList = getCredentialOptionInfoList(
it.providerFlattenedComponentName, it.credentialEntries, context),
authenticationEntry = getAuthenticationEntry(
it.providerFlattenedComponentName, it.authenticationEntry, context),
actionEntryList = getActionEntryList(
it.providerFlattenedComponentName, it.actionChips, context),
)
}
}
/* From service data structure to UI credential entry list representation. */
private fun getCredentialOptionInfoList(
providerId: String,
credentialEntries: List<Entry>,
context: Context,
): List<CredentialEntryInfo> {
return credentialEntries.map {
val credentialEntryUi = CredentialEntryUi.fromSlice(it.slice)
// Consider directly move the UI object into the class.
return@map CredentialEntryInfo(
providerId = providerId,
entryKey = it.key,
entrySubkey = it.subkey,
credentialType = credentialEntryUi.credentialType.toString(),
credentialTypeDisplayName = credentialEntryUi.credentialTypeDisplayName.toString(),
userName = credentialEntryUi.userName.toString(),
displayName = credentialEntryUi.userDisplayName?.toString(),
// TODO: proper fallback
icon = credentialEntryUi.entryIcon.loadDrawable(context)
?: context.getDrawable(R.drawable.ic_passkey)!!,
lastUsedTimeMillis = credentialEntryUi.lastUsedTimeMillis,
)
}
}
private fun getAuthenticationEntry(
providerId: String,
authEntry: Entry?,
context: Context,
): AuthenticationEntryInfo? {
// TODO: implement
return null
}
private fun getActionEntryList(
providerId: String,
actionEntries: List<Entry>,
context: Context,
): List<ActionEntryInfo> {
// TODO: implement
return emptyList()
}
}
}
class CreateFlowUtils {
companion object {
fun toEnabledProviderList(
providerDataList: List<CreateCredentialProviderData>,
context: Context,
): List<com.android.credentialmanager.createflow.EnabledProviderInfo> {
val packageManager = context.packageManager
return providerDataList.map {
val pkgInfo = packageManager
.getPackageInfo(it.providerFlattenedComponentName,
PackageManager.PackageInfoFlags.of(0))
com.android.credentialmanager.createflow.EnabledProviderInfo(
icon = pkgInfo.applicationInfo.loadIcon(packageManager)!!,
name = it.providerFlattenedComponentName,
displayName = pkgInfo.applicationInfo.loadLabel(packageManager).toString(),
createOptions = toCreationOptionInfoList(it.saveEntries, context),
isDefault = it.isDefaultProvider,
remoteEntry = toRemoteInfo(it.remoteEntry),
)
}
}
fun toDisabledProviderList(
providerDataList: List<DisabledProviderData>,
context: Context,
): List<com.android.credentialmanager.createflow.DisabledProviderInfo> {
val packageManager = context.packageManager
return providerDataList.map {
val pkgInfo = packageManager
.getPackageInfo(it.providerFlattenedComponentName,
PackageManager.PackageInfoFlags.of(0))
com.android.credentialmanager.createflow.DisabledProviderInfo(
icon = pkgInfo.applicationInfo.loadIcon(packageManager)!!,
name = it.providerFlattenedComponentName,
displayName = pkgInfo.applicationInfo.loadLabel(packageManager).toString(),
)
}
}
private fun toCreationOptionInfoList(
creationEntries: List<Entry>,
context: Context,
): List<CreateOptionInfo> {
return creationEntries.map {
val saveEntryUi = SaveEntryUi.fromSlice(it.slice)
return@map CreateOptionInfo(
// TODO: remove fallbacks
entryKey = it.key,
entrySubkey = it.subkey,
userProviderDisplayName = saveEntryUi.userProviderAccountName as String,
credentialTypeIcon = saveEntryUi.credentialTypeIcon?.loadDrawable(context)
?: context.getDrawable(R.drawable.ic_passkey)!!,
profileIcon = saveEntryUi.profileIcon?.loadDrawable(context)
?: context.getDrawable(R.drawable.ic_profile)!!,
passwordCount = saveEntryUi.passwordCount ?: 0,
passkeyCount = saveEntryUi.passkeyCount ?: 0,
totalCredentialCount = saveEntryUi.totalCredentialCount ?: 0,
lastUsedTimeMillis = saveEntryUi.lastUsedTimeMillis ?: 0,
)
}
}
private fun toRemoteInfo(
remoteEntry: Entry?,
): RemoteInfo? {
// TODO: should also call fromSlice after getting the official jetpack code.
return if (remoteEntry != null) {
RemoteInfo(
entryKey = remoteEntry.key,
entrySubkey = remoteEntry.subkey,
)
} else null
}
}
}