Loading packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt +16 −4 Original line number Diff line number Diff line Loading @@ -42,11 +42,13 @@ import com.android.credentialmanager.createflow.DisabledProviderInfo import com.android.credentialmanager.createflow.EnabledProviderInfo import com.android.credentialmanager.createflow.RequestDisplayInfo import com.android.credentialmanager.getflow.GetCredentialUiState import com.android.credentialmanager.getflow.findAutoSelectEntry import androidx.credentials.CreateCredentialRequest.DisplayInfo import androidx.credentials.CreatePublicKeyCredentialRequest import androidx.credentials.CreatePasswordRequest import androidx.credentials.GetPasswordOption import androidx.credentials.GetPublicKeyCredentialOption import com.android.credentialmanager.common.ProviderActivityState import java.time.Instant Loading Loading @@ -128,10 +130,20 @@ class CredentialManagerRepo( getCredentialUiState = null, ) } RequestInfo.TYPE_GET -> UiState( RequestInfo.TYPE_GET -> { val getCredentialInitialUiState = getCredentialInitialUiState(originName)!! val autoSelectEntry = findAutoSelectEntry(getCredentialInitialUiState.providerDisplayInfo) UiState( createCredentialUiState = null, getCredentialUiState = getCredentialInitialUiState(originName)!!, getCredentialUiState = getCredentialInitialUiState, selectedEntry = autoSelectEntry, providerActivityState = if (autoSelectEntry == null) ProviderActivityState.NOT_APPLICABLE else ProviderActivityState.READY_TO_LAUNCH, isAutoSelectFlow = autoSelectEntry != null, ) } else -> throw IllegalStateException("Unrecognized request type: ${requestInfo.type}") } } Loading packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt +17 −7 Original line number Diff line number Diff line Loading @@ -44,6 +44,9 @@ data class UiState( val selectedEntry: BaseEntry? = null, val providerActivityState: ProviderActivityState = ProviderActivityState.NOT_APPLICABLE, val dialogState: DialogState = DialogState.ACTIVE, // True if the UI has one and onely one auto selectable entry. Its provider activiey will be // launched immediately, and canceling it will cancel the whole UI flow. val isAutoSelectFlow: Boolean = false, ) class CredentialSelectorViewModel( Loading Loading @@ -96,13 +99,20 @@ class CredentialSelectorViewModel( val resultCode = providerActivityResult.resultCode val resultData = providerActivityResult.data if (resultCode == Activity.RESULT_CANCELED) { // Re-display the CredMan UI if the user canceled from the provider UI. // Re-display the CredMan UI if the user canceled from the provider UI, or cancel // the UI if this is the auto select flow. if (uiState.isAutoSelectFlow) { Log.d(Constants.LOG_TAG, "The auto selected provider activity was cancelled," + " ending the credential manager activity.") onUserCancel() } else { Log.d(Constants.LOG_TAG, "The provider activity was cancelled," + " re-displaying our UI.") uiState = uiState.copy( selectedEntry = null, providerActivityState = ProviderActivityState.NOT_APPLICABLE, ) } } else { if (entry != null) { Log.d( Loading packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt +6 −0 Original line number Diff line number Diff line Loading @@ -228,6 +228,8 @@ class GetFlowUtils { icon = credentialEntry.icon.loadDrawable(context), shouldTintIcon = credentialEntry.isDefaultIcon ?: false, lastUsedTimeMillis = credentialEntry.lastUsedTime, isAutoSelectable = credentialEntry.isAutoSelectAllowed && credentialEntry.autoSelectAllowedFromOption, )) } is PublicKeyCredentialEntry -> { Loading @@ -245,6 +247,8 @@ class GetFlowUtils { icon = credentialEntry.icon.loadDrawable(context), shouldTintIcon = credentialEntry.isDefaultIcon, lastUsedTimeMillis = credentialEntry.lastUsedTime, isAutoSelectable = credentialEntry.isAutoSelectAllowed && credentialEntry.autoSelectAllowedFromOption, )) } is CustomCredentialEntry -> { Loading @@ -262,6 +266,8 @@ class GetFlowUtils { icon = credentialEntry.icon.loadDrawable(context), shouldTintIcon = credentialEntry.isDefaultIcon, lastUsedTimeMillis = credentialEntry.lastUsedTime, isAutoSelectable = credentialEntry.isAutoSelectAllowed && credentialEntry.autoSelectAllowedFromOption, )) } else -> Log.d( Loading packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt +11 −9 Original line number Diff line number Diff line Loading @@ -155,21 +155,23 @@ class GetTestUtils { userName: String, userDisplayName: String?, lastUsedTime: Instant?, isAutoSelectAllowed: Boolean = false, ): Entry { val intent = Intent("com.androidauth.androidvault.CONFIRM_PASSWORD") .setPackage("com.androidauth.androidvault") intent.putExtra("provider_extra_sample", "testprovider") val pendingIntent = PendingIntent.getActivity( context, 1, intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_ONE_SHOT) val intent = Intent(Settings.ACTION_SYNC_SETTINGS) val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) val candidateQueryData = Bundle() candidateQueryData.putBoolean( "androidx.credentials.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED", isAutoSelectAllowed ) val passkeyEntry = PublicKeyCredentialEntry.Builder( context, userName, pendingIntent, BeginGetPublicKeyCredentialOption(Bundle(), "id", "requestjson") ).setDisplayName(userDisplayName).setLastUsedTime(lastUsedTime).build() BeginGetPublicKeyCredentialOption(candidateQueryData, "id", "requestjson") ).setDisplayName(userDisplayName).setLastUsedTime(lastUsedTime) .setAutoSelectAllowed(isAutoSelectAllowed).build() return Entry(key, subkey, passkeyEntry.slice, Intent()) } } Loading packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt +15 −2 Original line number Diff line number Diff line @file:OptIn(ExperimentalMaterial3Api::class) /* * 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.createflow Loading @@ -15,7 +29,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.material3.Divider import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.NewReleases Loading Loading
packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt +16 −4 Original line number Diff line number Diff line Loading @@ -42,11 +42,13 @@ import com.android.credentialmanager.createflow.DisabledProviderInfo import com.android.credentialmanager.createflow.EnabledProviderInfo import com.android.credentialmanager.createflow.RequestDisplayInfo import com.android.credentialmanager.getflow.GetCredentialUiState import com.android.credentialmanager.getflow.findAutoSelectEntry import androidx.credentials.CreateCredentialRequest.DisplayInfo import androidx.credentials.CreatePublicKeyCredentialRequest import androidx.credentials.CreatePasswordRequest import androidx.credentials.GetPasswordOption import androidx.credentials.GetPublicKeyCredentialOption import com.android.credentialmanager.common.ProviderActivityState import java.time.Instant Loading Loading @@ -128,10 +130,20 @@ class CredentialManagerRepo( getCredentialUiState = null, ) } RequestInfo.TYPE_GET -> UiState( RequestInfo.TYPE_GET -> { val getCredentialInitialUiState = getCredentialInitialUiState(originName)!! val autoSelectEntry = findAutoSelectEntry(getCredentialInitialUiState.providerDisplayInfo) UiState( createCredentialUiState = null, getCredentialUiState = getCredentialInitialUiState(originName)!!, getCredentialUiState = getCredentialInitialUiState, selectedEntry = autoSelectEntry, providerActivityState = if (autoSelectEntry == null) ProviderActivityState.NOT_APPLICABLE else ProviderActivityState.READY_TO_LAUNCH, isAutoSelectFlow = autoSelectEntry != null, ) } else -> throw IllegalStateException("Unrecognized request type: ${requestInfo.type}") } } Loading
packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt +17 −7 Original line number Diff line number Diff line Loading @@ -44,6 +44,9 @@ data class UiState( val selectedEntry: BaseEntry? = null, val providerActivityState: ProviderActivityState = ProviderActivityState.NOT_APPLICABLE, val dialogState: DialogState = DialogState.ACTIVE, // True if the UI has one and onely one auto selectable entry. Its provider activiey will be // launched immediately, and canceling it will cancel the whole UI flow. val isAutoSelectFlow: Boolean = false, ) class CredentialSelectorViewModel( Loading Loading @@ -96,13 +99,20 @@ class CredentialSelectorViewModel( val resultCode = providerActivityResult.resultCode val resultData = providerActivityResult.data if (resultCode == Activity.RESULT_CANCELED) { // Re-display the CredMan UI if the user canceled from the provider UI. // Re-display the CredMan UI if the user canceled from the provider UI, or cancel // the UI if this is the auto select flow. if (uiState.isAutoSelectFlow) { Log.d(Constants.LOG_TAG, "The auto selected provider activity was cancelled," + " ending the credential manager activity.") onUserCancel() } else { Log.d(Constants.LOG_TAG, "The provider activity was cancelled," + " re-displaying our UI.") uiState = uiState.copy( selectedEntry = null, providerActivityState = ProviderActivityState.NOT_APPLICABLE, ) } } else { if (entry != null) { Log.d( Loading
packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt +6 −0 Original line number Diff line number Diff line Loading @@ -228,6 +228,8 @@ class GetFlowUtils { icon = credentialEntry.icon.loadDrawable(context), shouldTintIcon = credentialEntry.isDefaultIcon ?: false, lastUsedTimeMillis = credentialEntry.lastUsedTime, isAutoSelectable = credentialEntry.isAutoSelectAllowed && credentialEntry.autoSelectAllowedFromOption, )) } is PublicKeyCredentialEntry -> { Loading @@ -245,6 +247,8 @@ class GetFlowUtils { icon = credentialEntry.icon.loadDrawable(context), shouldTintIcon = credentialEntry.isDefaultIcon, lastUsedTimeMillis = credentialEntry.lastUsedTime, isAutoSelectable = credentialEntry.isAutoSelectAllowed && credentialEntry.autoSelectAllowedFromOption, )) } is CustomCredentialEntry -> { Loading @@ -262,6 +266,8 @@ class GetFlowUtils { icon = credentialEntry.icon.loadDrawable(context), shouldTintIcon = credentialEntry.isDefaultIcon, lastUsedTimeMillis = credentialEntry.lastUsedTime, isAutoSelectable = credentialEntry.isAutoSelectAllowed && credentialEntry.autoSelectAllowedFromOption, )) } else -> Log.d( Loading
packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt +11 −9 Original line number Diff line number Diff line Loading @@ -155,21 +155,23 @@ class GetTestUtils { userName: String, userDisplayName: String?, lastUsedTime: Instant?, isAutoSelectAllowed: Boolean = false, ): Entry { val intent = Intent("com.androidauth.androidvault.CONFIRM_PASSWORD") .setPackage("com.androidauth.androidvault") intent.putExtra("provider_extra_sample", "testprovider") val pendingIntent = PendingIntent.getActivity( context, 1, intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_ONE_SHOT) val intent = Intent(Settings.ACTION_SYNC_SETTINGS) val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) val candidateQueryData = Bundle() candidateQueryData.putBoolean( "androidx.credentials.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED", isAutoSelectAllowed ) val passkeyEntry = PublicKeyCredentialEntry.Builder( context, userName, pendingIntent, BeginGetPublicKeyCredentialOption(Bundle(), "id", "requestjson") ).setDisplayName(userDisplayName).setLastUsedTime(lastUsedTime).build() BeginGetPublicKeyCredentialOption(candidateQueryData, "id", "requestjson") ).setDisplayName(userDisplayName).setLastUsedTime(lastUsedTime) .setAutoSelectAllowed(isAutoSelectAllowed).build() return Entry(key, subkey, passkeyEntry.slice, Intent()) } } Loading
packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt +15 −2 Original line number Diff line number Diff line @file:OptIn(ExperimentalMaterial3Api::class) /* * 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.createflow Loading @@ -15,7 +29,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.material3.Divider import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.NewReleases Loading