Loading packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt +21 −11 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import com.android.credentialmanager.createflow.RequestDisplayInfo import com.android.credentialmanager.getflow.GetCredentialUiState import com.android.credentialmanager.getflow.findAutoSelectEntry import com.android.credentialmanager.common.ProviderActivityState import com.android.credentialmanager.createflow.isFlowAutoSelectable /** * Client for interacting with Credential Manager. Also holds data inputs from it. Loading Loading @@ -113,8 +114,7 @@ class CredentialManagerRepo( val providerDisableListUiState = getCreateProviderDisableListInitialUiState() val requestDisplayInfoUiState = getCreateRequestDisplayInfoInitialUiState(originName)!! UiState( createCredentialUiState = CreateFlowUtils.toCreateCredentialUiState( val createCredentialUiState = CreateFlowUtils.toCreateCredentialUiState( enabledProviders = providerEnableListUiState, disabledProviders = providerDisableListUiState, defaultProviderIdPreferredByApp = Loading @@ -124,10 +124,20 @@ class CredentialManagerRepo( requestDisplayInfo = requestDisplayInfoUiState, isOnPasskeyIntroStateAlready = false, isPasskeyFirstUse = isPasskeyFirstUse, )!!, )!! val isFlowAutoSelectable = isFlowAutoSelectable(createCredentialUiState) UiState( createCredentialUiState = createCredentialUiState, getCredentialUiState = null, cancelRequestState = cancelUiRequestState, isInitialRender = isNewActivity, isAutoSelectFlow = isFlowAutoSelectable, providerActivityState = if (isFlowAutoSelectable) ProviderActivityState.READY_TO_LAUNCH else ProviderActivityState.NOT_APPLICABLE, selectedEntry = if (isFlowAutoSelectable) createCredentialUiState.activeEntry?.activeEntryInfo else null, ) } RequestInfo.TYPE_GET -> { Loading packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt +23 −13 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import com.android.credentialmanager.common.DialogState import com.android.credentialmanager.common.ProviderActivityResult import com.android.credentialmanager.common.ProviderActivityState import com.android.credentialmanager.createflow.ActiveEntry import com.android.credentialmanager.createflow.isFlowAutoSelectable import com.android.credentialmanager.createflow.CreateCredentialUiState import com.android.credentialmanager.createflow.CreateScreenState import com.android.credentialmanager.getflow.GetCredentialUiState Loading Loading @@ -262,30 +263,39 @@ class CredentialSelectorViewModel( /***** Create Flow Callbacks *****/ /**************************************************************************/ fun createFlowOnConfirmIntro() { userConfigRepo.setIsPasskeyFirstUse(false) val prevUiState = uiState.createCredentialUiState if (prevUiState == null) { Log.d(Constants.LOG_TAG, "Encountered unexpected null create ui state") onInternalError() return } val newUiState = CreateFlowUtils.toCreateCredentialUiState( enabledProviders = prevUiState.enabledProviders, disabledProviders = prevUiState.disabledProviders, defaultProviderIdPreferredByApp = prevUiState.requestDisplayInfo.appPreferredDefaultProviderId, defaultProviderIdsSetByUser = prevUiState.requestDisplayInfo.userSetDefaultProviderIds, requestDisplayInfo = prevUiState.requestDisplayInfo, val newScreenState = CreateFlowUtils.toCreateScreenState( createOptionSize = prevUiState.sortedCreateOptionsPairs.size, isOnPasskeyIntroStateAlready = true, isPasskeyFirstUse = userConfigRepo.getIsPasskeyFirstUse() requestDisplayInfo = prevUiState.requestDisplayInfo, remoteEntry = prevUiState.remoteEntry, isPasskeyFirstUse = true, ) if (newUiState == null) { Log.d(Constants.LOG_TAG, "Unable to update create ui state") if (newScreenState == null) { Log.d(Constants.LOG_TAG, "Unexpected: couldn't resolve new screen state") onInternalError() return } uiState = uiState.copy(createCredentialUiState = newUiState) userConfigRepo.setIsPasskeyFirstUse(false) val newCreateCredentialUiState = prevUiState.copy( currentScreenState = newScreenState, ) val isFlowAutoSelectable = isFlowAutoSelectable(newCreateCredentialUiState) uiState = uiState.copy( createCredentialUiState = newCreateCredentialUiState, isAutoSelectFlow = isFlowAutoSelectable, providerActivityState = if (isFlowAutoSelectable) ProviderActivityState.READY_TO_LAUNCH else ProviderActivityState.NOT_APPLICABLE, selectedEntry = if (isFlowAutoSelectable) newCreateCredentialUiState.activeEntry?.activeEntryInfo else null, ) } fun createFlowOnMoreOptionsSelectedOnCreationSelection() { Loading packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt +13 −2 Original line number Diff line number Diff line Loading @@ -487,6 +487,7 @@ class CreateFlowUtils { createCredentialRequestJetpack.preferImmediatelyAvailableCredentials, appPreferredDefaultProviderId = appPreferredDefaultProviderId, userSetDefaultProviderIds = requestInfo.defaultProviderIds.toSet(), isAutoSelectRequest = createCredentialRequestJetpack.isAutoSelectAllowed, ) is CreatePublicKeyCredentialRequest -> { newRequestDisplayInfoFromPasskeyJson( Loading @@ -497,6 +498,7 @@ class CreateFlowUtils { createCredentialRequestJetpack.preferImmediatelyAvailableCredentials, appPreferredDefaultProviderId = appPreferredDefaultProviderId, userSetDefaultProviderIds = requestInfo.defaultProviderIds.toSet(), isAutoSelectRequest = createCredentialRequestJetpack.isAutoSelectAllowed, ) } is CreateCustomCredentialRequest -> { Loading @@ -515,6 +517,7 @@ class CreateFlowUtils { createCredentialRequestJetpack.preferImmediatelyAvailableCredentials, appPreferredDefaultProviderId = appPreferredDefaultProviderId, userSetDefaultProviderIds = requestInfo.defaultProviderIds.toSet(), isAutoSelectRequest = createCredentialRequestJetpack.isAutoSelectAllowed, ) } else -> null Loading Loading @@ -602,7 +605,7 @@ class CreateFlowUtils { ) } private fun toCreateScreenState( fun toCreateScreenState( createOptionSize: Int, isOnPasskeyIntroStateAlready: Boolean, requestDisplayInfo: RequestDisplayInfo, Loading Loading @@ -662,7 +665,13 @@ class CreateFlowUtils { passkeyCount = createEntry.getPublicKeyCredentialCount(), totalCredentialCount = createEntry.getTotalCredentialCount(), lastUsedTime = createEntry.lastUsedTime ?: Instant.MIN, footerDescription = createEntry.description?.toString() footerDescription = createEntry.description?.toString(), // TODO(b/281065680): replace with official library constant once available allowAutoSelect = it.slice.items.firstOrNull { it.hasHint("androidx.credentials.provider.createEntry.SLICE_HINT_AUTO_" + "SELECT_ALLOWED") }?.text == "true", )) } return result.sortedWith( Loading Loading @@ -694,6 +703,7 @@ class CreateFlowUtils { preferImmediatelyAvailableCredentials: Boolean, appPreferredDefaultProviderId: String?, userSetDefaultProviderIds: Set<String>, isAutoSelectRequest: Boolean ): RequestDisplayInfo? { val json = JSONObject(requestJson) var passkeyUsername = "" Loading @@ -716,6 +726,7 @@ class CreateFlowUtils { preferImmediatelyAvailableCredentials, appPreferredDefaultProviderId, userSetDefaultProviderIds, isAutoSelectRequest, ) } } Loading packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt +4 −2 Original line number Diff line number Diff line Loading @@ -39,14 +39,16 @@ fun ModalBottomSheet( onDismiss: () -> Unit, isInitialRender: Boolean, onInitialRenderComplete: () -> Unit, isAutoSelectFlow: Boolean, ) { val scope = rememberCoroutineScope() val state = rememberModalBottomSheetState( initialValue = ModalBottomSheetValue.Hidden, initialValue = if (isAutoSelectFlow) ModalBottomSheetValue.Expanded else ModalBottomSheetValue.Hidden, skipHalfExpanded = true ) val sysUiController = rememberSystemUiController() if (state.targetValue == ModalBottomSheetValue.Hidden) { if (state.targetValue == ModalBottomSheetValue.Hidden || isAutoSelectFlow) { setTransparentSystemBarsColor(sysUiController) } else { setBottomSheetSystemBarsColor(sysUiController) Loading packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt +1 −0 Original line number Diff line number Diff line Loading @@ -166,6 +166,7 @@ fun CreateCredentialScreen( }, onDismiss = viewModel::onUserCancel, isInitialRender = viewModel.uiState.isInitialRender, isAutoSelectFlow = viewModel.uiState.isAutoSelectFlow, onInitialRenderComplete = viewModel::onInitialRenderComplete, ) } Loading Loading
packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt +21 −11 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import com.android.credentialmanager.createflow.RequestDisplayInfo import com.android.credentialmanager.getflow.GetCredentialUiState import com.android.credentialmanager.getflow.findAutoSelectEntry import com.android.credentialmanager.common.ProviderActivityState import com.android.credentialmanager.createflow.isFlowAutoSelectable /** * Client for interacting with Credential Manager. Also holds data inputs from it. Loading Loading @@ -113,8 +114,7 @@ class CredentialManagerRepo( val providerDisableListUiState = getCreateProviderDisableListInitialUiState() val requestDisplayInfoUiState = getCreateRequestDisplayInfoInitialUiState(originName)!! UiState( createCredentialUiState = CreateFlowUtils.toCreateCredentialUiState( val createCredentialUiState = CreateFlowUtils.toCreateCredentialUiState( enabledProviders = providerEnableListUiState, disabledProviders = providerDisableListUiState, defaultProviderIdPreferredByApp = Loading @@ -124,10 +124,20 @@ class CredentialManagerRepo( requestDisplayInfo = requestDisplayInfoUiState, isOnPasskeyIntroStateAlready = false, isPasskeyFirstUse = isPasskeyFirstUse, )!!, )!! val isFlowAutoSelectable = isFlowAutoSelectable(createCredentialUiState) UiState( createCredentialUiState = createCredentialUiState, getCredentialUiState = null, cancelRequestState = cancelUiRequestState, isInitialRender = isNewActivity, isAutoSelectFlow = isFlowAutoSelectable, providerActivityState = if (isFlowAutoSelectable) ProviderActivityState.READY_TO_LAUNCH else ProviderActivityState.NOT_APPLICABLE, selectedEntry = if (isFlowAutoSelectable) createCredentialUiState.activeEntry?.activeEntryInfo else null, ) } RequestInfo.TYPE_GET -> { Loading
packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt +23 −13 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import com.android.credentialmanager.common.DialogState import com.android.credentialmanager.common.ProviderActivityResult import com.android.credentialmanager.common.ProviderActivityState import com.android.credentialmanager.createflow.ActiveEntry import com.android.credentialmanager.createflow.isFlowAutoSelectable import com.android.credentialmanager.createflow.CreateCredentialUiState import com.android.credentialmanager.createflow.CreateScreenState import com.android.credentialmanager.getflow.GetCredentialUiState Loading Loading @@ -262,30 +263,39 @@ class CredentialSelectorViewModel( /***** Create Flow Callbacks *****/ /**************************************************************************/ fun createFlowOnConfirmIntro() { userConfigRepo.setIsPasskeyFirstUse(false) val prevUiState = uiState.createCredentialUiState if (prevUiState == null) { Log.d(Constants.LOG_TAG, "Encountered unexpected null create ui state") onInternalError() return } val newUiState = CreateFlowUtils.toCreateCredentialUiState( enabledProviders = prevUiState.enabledProviders, disabledProviders = prevUiState.disabledProviders, defaultProviderIdPreferredByApp = prevUiState.requestDisplayInfo.appPreferredDefaultProviderId, defaultProviderIdsSetByUser = prevUiState.requestDisplayInfo.userSetDefaultProviderIds, requestDisplayInfo = prevUiState.requestDisplayInfo, val newScreenState = CreateFlowUtils.toCreateScreenState( createOptionSize = prevUiState.sortedCreateOptionsPairs.size, isOnPasskeyIntroStateAlready = true, isPasskeyFirstUse = userConfigRepo.getIsPasskeyFirstUse() requestDisplayInfo = prevUiState.requestDisplayInfo, remoteEntry = prevUiState.remoteEntry, isPasskeyFirstUse = true, ) if (newUiState == null) { Log.d(Constants.LOG_TAG, "Unable to update create ui state") if (newScreenState == null) { Log.d(Constants.LOG_TAG, "Unexpected: couldn't resolve new screen state") onInternalError() return } uiState = uiState.copy(createCredentialUiState = newUiState) userConfigRepo.setIsPasskeyFirstUse(false) val newCreateCredentialUiState = prevUiState.copy( currentScreenState = newScreenState, ) val isFlowAutoSelectable = isFlowAutoSelectable(newCreateCredentialUiState) uiState = uiState.copy( createCredentialUiState = newCreateCredentialUiState, isAutoSelectFlow = isFlowAutoSelectable, providerActivityState = if (isFlowAutoSelectable) ProviderActivityState.READY_TO_LAUNCH else ProviderActivityState.NOT_APPLICABLE, selectedEntry = if (isFlowAutoSelectable) newCreateCredentialUiState.activeEntry?.activeEntryInfo else null, ) } fun createFlowOnMoreOptionsSelectedOnCreationSelection() { Loading
packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt +13 −2 Original line number Diff line number Diff line Loading @@ -487,6 +487,7 @@ class CreateFlowUtils { createCredentialRequestJetpack.preferImmediatelyAvailableCredentials, appPreferredDefaultProviderId = appPreferredDefaultProviderId, userSetDefaultProviderIds = requestInfo.defaultProviderIds.toSet(), isAutoSelectRequest = createCredentialRequestJetpack.isAutoSelectAllowed, ) is CreatePublicKeyCredentialRequest -> { newRequestDisplayInfoFromPasskeyJson( Loading @@ -497,6 +498,7 @@ class CreateFlowUtils { createCredentialRequestJetpack.preferImmediatelyAvailableCredentials, appPreferredDefaultProviderId = appPreferredDefaultProviderId, userSetDefaultProviderIds = requestInfo.defaultProviderIds.toSet(), isAutoSelectRequest = createCredentialRequestJetpack.isAutoSelectAllowed, ) } is CreateCustomCredentialRequest -> { Loading @@ -515,6 +517,7 @@ class CreateFlowUtils { createCredentialRequestJetpack.preferImmediatelyAvailableCredentials, appPreferredDefaultProviderId = appPreferredDefaultProviderId, userSetDefaultProviderIds = requestInfo.defaultProviderIds.toSet(), isAutoSelectRequest = createCredentialRequestJetpack.isAutoSelectAllowed, ) } else -> null Loading Loading @@ -602,7 +605,7 @@ class CreateFlowUtils { ) } private fun toCreateScreenState( fun toCreateScreenState( createOptionSize: Int, isOnPasskeyIntroStateAlready: Boolean, requestDisplayInfo: RequestDisplayInfo, Loading Loading @@ -662,7 +665,13 @@ class CreateFlowUtils { passkeyCount = createEntry.getPublicKeyCredentialCount(), totalCredentialCount = createEntry.getTotalCredentialCount(), lastUsedTime = createEntry.lastUsedTime ?: Instant.MIN, footerDescription = createEntry.description?.toString() footerDescription = createEntry.description?.toString(), // TODO(b/281065680): replace with official library constant once available allowAutoSelect = it.slice.items.firstOrNull { it.hasHint("androidx.credentials.provider.createEntry.SLICE_HINT_AUTO_" + "SELECT_ALLOWED") }?.text == "true", )) } return result.sortedWith( Loading Loading @@ -694,6 +703,7 @@ class CreateFlowUtils { preferImmediatelyAvailableCredentials: Boolean, appPreferredDefaultProviderId: String?, userSetDefaultProviderIds: Set<String>, isAutoSelectRequest: Boolean ): RequestDisplayInfo? { val json = JSONObject(requestJson) var passkeyUsername = "" Loading @@ -716,6 +726,7 @@ class CreateFlowUtils { preferImmediatelyAvailableCredentials, appPreferredDefaultProviderId, userSetDefaultProviderIds, isAutoSelectRequest, ) } } Loading
packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt +4 −2 Original line number Diff line number Diff line Loading @@ -39,14 +39,16 @@ fun ModalBottomSheet( onDismiss: () -> Unit, isInitialRender: Boolean, onInitialRenderComplete: () -> Unit, isAutoSelectFlow: Boolean, ) { val scope = rememberCoroutineScope() val state = rememberModalBottomSheetState( initialValue = ModalBottomSheetValue.Hidden, initialValue = if (isAutoSelectFlow) ModalBottomSheetValue.Expanded else ModalBottomSheetValue.Hidden, skipHalfExpanded = true ) val sysUiController = rememberSystemUiController() if (state.targetValue == ModalBottomSheetValue.Hidden) { if (state.targetValue == ModalBottomSheetValue.Hidden || isAutoSelectFlow) { setTransparentSystemBarsColor(sysUiController) } else { setBottomSheetSystemBarsColor(sysUiController) Loading
packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt +1 −0 Original line number Diff line number Diff line Loading @@ -166,6 +166,7 @@ fun CreateCredentialScreen( }, onDismiss = viewModel::onUserCancel, isInitialRender = viewModel.uiState.isInitialRender, isAutoSelectFlow = viewModel.uiState.isAutoSelectFlow, onInitialRenderComplete = viewModel::onInitialRenderComplete, ) } Loading