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

Commit 1aef022b authored by Helen Qin's avatar Helen Qin
Browse files

Fix race condition between provider ui launching and credman ui update.

Hide CredMan UI has to happen before provider UI is launched. This fix
ensures this order.

Bug: 261229077
Test: local deployment
Change-Id: I7e7ef275f119386e833b6762801e3ee9eed6a423
parent e652c10b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ class CredentialSelectorActivity : ComponentActivity() {
        )
        providerActivityResult.value?.let {
          viewModel.onProviderActivityResult(it)
          providerActivityResult.value = null
        }
        CreateCredentialScreen(viewModel = viewModel, providerActivityLauncher = launcher)
      }
@@ -80,6 +81,7 @@ class CredentialSelectorActivity : ComponentActivity() {
        )
        providerActivityResult.value?.let {
          viewModel.onProviderActivityResult(it)
          providerActivityResult.value = null
        }
        GetCredentialScreen(viewModel = viewModel, providerActivityLauncher = launcher)
      }
+8 −12
Original line number Diff line number Diff line
@@ -60,12 +60,6 @@ fun CreateCredentialScreen(
    viewModel: CreateCredentialViewModel,
    providerActivityLauncher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
) {
    val selectEntryCallback: (EntryInfo) -> Unit = {
        viewModel.onEntrySelected(it, providerActivityLauncher)
    }
    val confirmEntryCallback: () -> Unit = {
        viewModel.onConfirmEntrySelected(providerActivityLauncher)
    }
    val state = rememberModalBottomSheetState(
        initialValue = ModalBottomSheetValue.Expanded,
        skipHalfExpanded = true
@@ -89,7 +83,7 @@ fun CreateCredentialScreen(
                        onOptionSelected = viewModel::onEntrySelectedFromFirstUseScreen,
                        onDisabledPasswordManagerSelected =
                        viewModel::onDisabledPasswordManagerSelected,
                        onRemoteEntrySelected = selectEntryCallback,
                        onRemoteEntrySelected = viewModel::onEntrySelected,
                    )
                    CreateScreenState.CREATION_OPTION_SELECTION -> CreationSelectionCard(
                        requestDisplayInfo = uiState.requestDisplayInfo,
@@ -97,8 +91,8 @@ fun CreateCredentialScreen(
                        providerInfo = uiState.activeEntry?.activeProvider!!,
                        createOptionInfo = uiState.activeEntry.activeEntryInfo as CreateOptionInfo,
                        showActiveEntryOnly = uiState.showActiveEntryOnly,
                        onOptionSelected = selectEntryCallback,
                        onConfirm = confirmEntryCallback,
                        onOptionSelected = viewModel::onEntrySelected,
                        onConfirm = viewModel::onConfirmEntrySelected,
                        onCancel = viewModel::onCancel,
                        onMoreOptionsSelected = viewModel::onMoreOptionsSelected,
                    )
@@ -110,7 +104,7 @@ fun CreateCredentialScreen(
                        onOptionSelected = viewModel::onEntrySelectedFromMoreOptionScreen,
                        onDisabledPasswordManagerSelected =
                        viewModel::onDisabledPasswordManagerSelected,
                        onRemoteEntrySelected = selectEntryCallback,
                        onRemoteEntrySelected = viewModel::onEntrySelected,
                    )
                    CreateScreenState.MORE_OPTIONS_ROW_INTRO -> MoreOptionsRowIntroCard(
                        providerInfo = uiState.activeEntry?.activeProvider!!,
@@ -119,11 +113,13 @@ fun CreateCredentialScreen(
                    CreateScreenState.EXTERNAL_ONLY_SELECTION -> ExternalOnlySelectionCard(
                        requestDisplayInfo = uiState.requestDisplayInfo,
                        activeRemoteEntry = uiState.activeEntry?.activeEntryInfo!!,
                        onOptionSelected = selectEntryCallback,
                        onConfirm = confirmEntryCallback,
                        onOptionSelected = viewModel::onEntrySelected,
                        onConfirm = viewModel::onConfirmEntrySelected,
                        onCancel = viewModel::onCancel,
                    )
                }
            } else if (uiState.hidden && uiState.selectedEntry != null) {
                viewModel.launchProviderUi(providerActivityLauncher)
            }
        },
        scrimColor = MaterialTheme.colorScheme.scrim.copy(alpha = 0.8f),
+14 −9
Original line number Diff line number Diff line
@@ -130,10 +130,7 @@ class CreateCredentialViewModel(
    // TODO: implement the if choose as default or not logic later
  }

  fun onEntrySelected(
    selectedEntry: EntryInfo,
    launcher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
  ) {
  fun onEntrySelected(selectedEntry: EntryInfo) {
    val providerId = selectedEntry.providerId
    val entryKey = selectedEntry.entryKey
    val entrySubkey = selectedEntry.entrySubkey
@@ -145,9 +142,6 @@ class CreateCredentialViewModel(
        selectedEntry = selectedEntry,
        hidden = true,
      )
      val intentSenderRequest = IntentSenderRequest.Builder(selectedEntry.pendingIntent)
        .setFillInIntent(selectedEntry.fillInIntent).build()
      launcher.launch(intentSenderRequest)
    } else {
      CredentialManagerRepo.getInstance().onOptionSelected(
        providerId,
@@ -160,12 +154,23 @@ class CreateCredentialViewModel(
    }
  }

  fun onConfirmEntrySelected(
  fun launchProviderUi(
    launcher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
  ) {
    val entry = uiState.selectedEntry
    if (entry != null && entry.pendingIntent != null) {
      val intentSenderRequest = IntentSenderRequest.Builder(entry.pendingIntent)
        .setFillInIntent(entry.fillInIntent).build()
      launcher.launch(intentSenderRequest)
    } else {
      Log.w("Account Selector", "No provider UI to launch")
    }
  }

  fun onConfirmEntrySelected() {
    val selectedEntry = uiState.activeEntry?.activeEntryInfo
    if (selectedEntry != null) {
      onEntrySelected(selectedEntry, launcher)
      onEntrySelected(selectedEntry)
    } else {
      Log.w("Account Selector",
        "Illegal state: confirm is pressed but activeEntry isn't set.")
+4 −5
Original line number Diff line number Diff line
@@ -71,9 +71,6 @@ fun GetCredentialScreen(
    viewModel: GetCredentialViewModel,
    providerActivityLauncher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
) {
    val entrySelectionCallback: (EntryInfo) -> Unit = {
        viewModel.onEntrySelected(it, providerActivityLauncher)
    }
    val state = rememberModalBottomSheetState(
        initialValue = ModalBottomSheetValue.Expanded,
        skipHalfExpanded = true
@@ -89,17 +86,19 @@ fun GetCredentialScreen(
                    GetScreenState.PRIMARY_SELECTION -> PrimarySelectionCard(
                        requestDisplayInfo = uiState.requestDisplayInfo,
                        providerDisplayInfo = uiState.providerDisplayInfo,
                        onEntrySelected = entrySelectionCallback,
                        onEntrySelected = viewModel::onEntrySelected,
                        onCancel = viewModel::onCancel,
                        onMoreOptionSelected = viewModel::onMoreOptionSelected,
                    )
                    GetScreenState.ALL_SIGN_IN_OPTIONS -> AllSignInOptionCard(
                        providerInfoList = uiState.providerInfoList,
                        providerDisplayInfo = uiState.providerDisplayInfo,
                        onEntrySelected = entrySelectionCallback,
                        onEntrySelected = viewModel::onEntrySelected,
                        onBackButtonClicked = viewModel::onBackToPrimarySelectionScreen,
                    )
                }
            } else if (uiState.hidden && uiState.selectedEntry != null) {
                viewModel.launchProviderUi(providerActivityLauncher)
            }
        },
        scrimColor = MaterialTheme.colorScheme.scrim.copy(alpha = 0.8f),
+14 −7
Original line number Diff line number Diff line
@@ -58,10 +58,7 @@ class GetCredentialViewModel(
    return dialogResult
  }

  fun onEntrySelected(
    entry: EntryInfo,
    launcher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
  ) {
  fun onEntrySelected(entry: EntryInfo) {
    Log.d("Account Selector", "credential selected:" +
            " {provider=${entry.providerId}, key=${entry.entryKey}, subkey=${entry.entrySubkey}}")
    if (entry.pendingIntent != null) {
@@ -69,9 +66,6 @@ class GetCredentialViewModel(
        selectedEntry = entry,
        hidden = true,
      )
      val intentSenderRequest = IntentSenderRequest.Builder(entry.pendingIntent)
        .setFillInIntent(entry.fillInIntent).build()
      launcher.launch(intentSenderRequest)
    } else {
      CredentialManagerRepo.getInstance().onOptionSelected(
        entry.providerId, entry.entryKey, entry.entrySubkey,
@@ -80,6 +74,19 @@ class GetCredentialViewModel(
    }
  }

  fun launchProviderUi(
    launcher: ManagedActivityResultLauncher<IntentSenderRequest, ActivityResult>
  ) {
    val entry = uiState.selectedEntry
    if (entry != null && entry.pendingIntent != null) {
      val intentSenderRequest = IntentSenderRequest.Builder(entry.pendingIntent)
        .setFillInIntent(entry.fillInIntent).build()
      launcher.launch(intentSenderRequest)
    } else {
      Log.w("Account Selector", "No provider UI to launch")
    }
  }

  fun onProviderActivityResult(providerActivityResult: ProviderActivityResult) {
    val entry = uiState.selectedEntry
    val resultCode = providerActivityResult.resultCode