diff options
| author | 2023-02-22 23:58:52 +0000 | |
|---|---|---|
| committer | 2023-03-06 22:25:27 +0000 | |
| commit | 9efe77677cb4bcda9ccb80f30720e1694b7707e8 (patch) | |
| tree | c48100a5440357dba053502cc604bea24c2b938d | |
| parent | 0dcaf197b42b7e995f6b7bd9c3fb3a7b622b255e (diff) | |
Add go/aster logging to CreateCredentialComponents
Bug: 270426258
Test: Local-Deployment(https://paste.googleplex.com/4896863487524864)
Change-Id: I0182c848bb20b521633c192aac7776468f177199
4 files changed, 248 insertions, 82 deletions
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt index a5c749432753..fd4b72a96199 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialSelectorViewModel.kt @@ -22,6 +22,7 @@ import android.util.Log import androidx.activity.compose.ManagedActivityResultLauncher import androidx.activity.result.ActivityResult import androidx.activity.result.IntentSenderRequest +import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue @@ -36,6 +37,8 @@ import com.android.credentialmanager.createflow.CreateCredentialUiState import com.android.credentialmanager.createflow.CreateScreenState import com.android.credentialmanager.getflow.GetCredentialUiState import com.android.credentialmanager.getflow.GetScreenState +import com.android.credentialmanager.logging.UIMetrics +import com.android.internal.logging.UiEventLogger.UiEventEnum /** One and only one of create or get state can be active at any given time. */ data class UiState( @@ -53,6 +56,8 @@ class CredentialSelectorViewModel( var uiState by mutableStateOf(credManRepo.initState()) private set + var uiMetrics: UIMetrics = UIMetrics() + /**************************************************************************/ /***** Shared Callbacks *****/ /**************************************************************************/ @@ -73,6 +78,10 @@ class CredentialSelectorViewModel( fun onNewCredentialManagerRepo(credManRepo: CredentialManagerRepo) { this.credManRepo = credManRepo uiState = credManRepo.initState() + + if (this.credManRepo.requestInfo.token != credManRepo.requestInfo.token) { + this.uiMetrics.resetInstanceId() + } } fun launchProviderUi( @@ -364,4 +373,9 @@ class CredentialSelectorViewModel( onInternalError() } } + + @Composable + fun logUiEvent(uiEventEnum: UiEventEnum) { + this.uiMetrics.log(uiEventEnum, credManRepo.requestInfo.appPackageName) + } }
\ No newline at end of file diff --git a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt index b83c593fdffc..064c3c64be94 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/createflow/CreateCredentialComponents.kt @@ -54,6 +54,8 @@ import com.android.credentialmanager.common.ui.SheetContainerCard import com.android.credentialmanager.common.ui.PasskeyBenefitRow import com.android.credentialmanager.common.ui.HeadlineText import com.android.credentialmanager.common.ui.setBottomSheetSystemBarsColor +import com.android.credentialmanager.logging.CreateCredentialEvent +import com.android.internal.logging.UiEventLogger.UiEventEnum @Composable fun CreateCredentialScreen( @@ -72,81 +74,93 @@ fun CreateCredentialScreen( ProviderActivityState.NOT_APPLICABLE -> { when (createCredentialUiState.currentScreenState) { CreateScreenState.PASSKEY_INTRO -> PasskeyIntroCard( - onConfirm = viewModel::createFlowOnConfirmIntro, - onLearnMore = viewModel::createFlowOnLearnMore, + onConfirm = viewModel::createFlowOnConfirmIntro, + onLearnMore = viewModel::createFlowOnLearnMore, + onLog = { viewModel.logUiEvent(it) }, ) CreateScreenState.PROVIDER_SELECTION -> ProviderSelectionCard( - requestDisplayInfo = createCredentialUiState.requestDisplayInfo, - disabledProviderList = createCredentialUiState.disabledProviders, - sortedCreateOptionsPairs = - createCredentialUiState.sortedCreateOptionsPairs, - hasRemoteEntry = createCredentialUiState.remoteEntry != null, - onOptionSelected = - viewModel::createFlowOnEntrySelectedFromFirstUseScreen, - onDisabledProvidersSelected = - viewModel::createFlowOnDisabledProvidersSelected, - onMoreOptionsSelected = - viewModel::createFlowOnMoreOptionsSelectedOnProviderSelection, + requestDisplayInfo = createCredentialUiState.requestDisplayInfo, + disabledProviderList = createCredentialUiState + .disabledProviders, + sortedCreateOptionsPairs = + createCredentialUiState.sortedCreateOptionsPairs, + hasRemoteEntry = createCredentialUiState.remoteEntry != null, + onOptionSelected = + viewModel::createFlowOnEntrySelectedFromFirstUseScreen, + onDisabledProvidersSelected = + viewModel::createFlowOnDisabledProvidersSelected, + onMoreOptionsSelected = + viewModel::createFlowOnMoreOptionsSelectedOnProviderSelection, + onLog = { viewModel.logUiEvent(it) }, ) CreateScreenState.CREATION_OPTION_SELECTION -> CreationSelectionCard( - requestDisplayInfo = createCredentialUiState.requestDisplayInfo, - enabledProviderList = createCredentialUiState.enabledProviders, - providerInfo = createCredentialUiState.activeEntry?.activeProvider!!, - hasDefaultProvider = createCredentialUiState.hasDefaultProvider, - createOptionInfo = - createCredentialUiState.activeEntry.activeEntryInfo - as CreateOptionInfo, - onOptionSelected = viewModel::createFlowOnEntrySelected, - onConfirm = viewModel::createFlowOnConfirmEntrySelected, - onMoreOptionsSelected = - viewModel::createFlowOnMoreOptionsSelectedOnCreationSelection, + requestDisplayInfo = createCredentialUiState.requestDisplayInfo, + enabledProviderList = createCredentialUiState.enabledProviders, + providerInfo = createCredentialUiState + .activeEntry?.activeProvider!!, + hasDefaultProvider = createCredentialUiState.hasDefaultProvider, + createOptionInfo = + createCredentialUiState.activeEntry.activeEntryInfo + as CreateOptionInfo, + onOptionSelected = viewModel::createFlowOnEntrySelected, + onConfirm = viewModel::createFlowOnConfirmEntrySelected, + onMoreOptionsSelected = + viewModel::createFlowOnMoreOptionsSelectedOnCreationSelection, + onLog = { viewModel.logUiEvent(it) }, ) CreateScreenState.MORE_OPTIONS_SELECTION -> MoreOptionsSelectionCard( - requestDisplayInfo = createCredentialUiState.requestDisplayInfo, - enabledProviderList = createCredentialUiState.enabledProviders, - disabledProviderList = createCredentialUiState.disabledProviders, - sortedCreateOptionsPairs = - createCredentialUiState.sortedCreateOptionsPairs, - hasDefaultProvider = createCredentialUiState.hasDefaultProvider, - isFromProviderSelection = - createCredentialUiState.isFromProviderSelection!!, - onBackProviderSelectionButtonSelected = - viewModel::createFlowOnBackProviderSelectionButtonSelected, - onBackCreationSelectionButtonSelected = - viewModel::createFlowOnBackCreationSelectionButtonSelected, - onOptionSelected = - viewModel::createFlowOnEntrySelectedFromMoreOptionScreen, - onDisabledProvidersSelected = - viewModel::createFlowOnDisabledProvidersSelected, - onRemoteEntrySelected = viewModel::createFlowOnEntrySelected, + requestDisplayInfo = createCredentialUiState.requestDisplayInfo, + enabledProviderList = createCredentialUiState.enabledProviders, + disabledProviderList = createCredentialUiState + .disabledProviders, + sortedCreateOptionsPairs = + createCredentialUiState.sortedCreateOptionsPairs, + hasDefaultProvider = createCredentialUiState.hasDefaultProvider, + isFromProviderSelection = + createCredentialUiState.isFromProviderSelection!!, + onBackProviderSelectionButtonSelected = + viewModel::createFlowOnBackProviderSelectionButtonSelected, + onBackCreationSelectionButtonSelected = + viewModel::createFlowOnBackCreationSelectionButtonSelected, + onOptionSelected = + viewModel::createFlowOnEntrySelectedFromMoreOptionScreen, + onDisabledProvidersSelected = + viewModel::createFlowOnDisabledProvidersSelected, + onRemoteEntrySelected = viewModel::createFlowOnEntrySelected, + onLog = { viewModel.logUiEvent(it) }, ) CreateScreenState.MORE_OPTIONS_ROW_INTRO -> { if (createCredentialUiState.activeEntry == null) { viewModel.onIllegalUiState("Expect active entry to be non-null" + - " upon default provider dialog.") + " upon default provider dialog.") } else { MoreOptionsRowIntroCard( - selectedEntry = createCredentialUiState.activeEntry, - onIllegalScreenState = viewModel::onIllegalUiState, - onChangeDefaultSelected = - viewModel::createFlowOnChangeDefaultSelected, - onUseOnceSelected = viewModel::createFlowOnUseOnceSelected, + selectedEntry = createCredentialUiState.activeEntry, + onIllegalScreenState = viewModel::onIllegalUiState, + onChangeDefaultSelected = + viewModel::createFlowOnChangeDefaultSelected, + onUseOnceSelected = viewModel::createFlowOnUseOnceSelected, + onLog = { viewModel.logUiEvent(it) }, ) } } CreateScreenState.EXTERNAL_ONLY_SELECTION -> ExternalOnlySelectionCard( - requestDisplayInfo = createCredentialUiState.requestDisplayInfo, - activeRemoteEntry = - createCredentialUiState.activeEntry?.activeEntryInfo!!, - onOptionSelected = viewModel::createFlowOnEntrySelected, - onConfirm = viewModel::createFlowOnConfirmEntrySelected, + requestDisplayInfo = createCredentialUiState.requestDisplayInfo, + activeRemoteEntry = + createCredentialUiState.activeEntry?.activeEntryInfo!!, + onOptionSelected = viewModel::createFlowOnEntrySelected, + onConfirm = viewModel::createFlowOnConfirmEntrySelected, + onLog = { viewModel.logUiEvent(it) }, ) - CreateScreenState.MORE_ABOUT_PASSKEYS_INTRO -> - MoreAboutPasskeysIntroCard( + CreateScreenState.MORE_ABOUT_PASSKEYS_INTRO -> MoreAboutPasskeysIntroCard( onBackPasskeyIntroButtonSelected = viewModel::createFlowOnBackPasskeyIntroButtonSelected, - ) + onLog = { viewModel.logUiEvent(it) }, + ) } + viewModel.uiMetrics.log( + CreateCredentialEvent + .CREDMAN_CREATE_CRED_PROVIDER_ACTIVITY_NOT_APPLICABLE) } ProviderActivityState.READY_TO_LAUNCH -> { // Launch only once per providerActivityState change so that the provider @@ -154,9 +168,14 @@ fun CreateCredentialScreen( LaunchedEffect(viewModel.uiState.providerActivityState) { viewModel.launchProviderUi(providerActivityLauncher) } + viewModel.uiMetrics.log( + CreateCredentialEvent + .CREDMAN_CREATE_CRED_PROVIDER_ACTIVITY_READY_TO_LAUNCH) } ProviderActivityState.PENDING -> { // Hide our content when the provider activity is active. + viewModel.uiMetrics.log( + CreateCredentialEvent.CREDMAN_CREATE_CRED_PROVIDER_ACTIVITY_PENDING) } } }, @@ -168,6 +187,7 @@ fun CreateCredentialScreen( fun PasskeyIntroCard( onConfirm: () -> Unit, onLearnMore: () -> Unit, + onLog: @Composable (UiEventEnum) -> Unit, ) { SheetContainerCard { item { @@ -232,6 +252,7 @@ fun PasskeyIntroCard( ) } } + onLog(CreateCredentialEvent.CREDMAN_CREATE_CRED_PASSKEY_INTRO) } @Composable @@ -243,6 +264,7 @@ fun ProviderSelectionCard( onOptionSelected: (ActiveEntry) -> Unit, onDisabledProvidersSelected: () -> Unit, onMoreOptionsSelected: () -> Unit, + onLog: @Composable (UiEventEnum) -> Unit, ) { SheetContainerCard { item { HeadlineIcon(bitmap = requestDisplayInfo.typeIcon.toBitmap().asImageBitmap()) } @@ -306,21 +328,23 @@ fun ProviderSelectionCard( } } } + onLog(CreateCredentialEvent.CREDMAN_CREATE_CRED_PROVIDER_SELECTION) } @Composable fun MoreOptionsSelectionCard( - requestDisplayInfo: RequestDisplayInfo, - enabledProviderList: List<EnabledProviderInfo>, - disabledProviderList: List<DisabledProviderInfo>?, - sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>, - hasDefaultProvider: Boolean, - isFromProviderSelection: Boolean, - onBackProviderSelectionButtonSelected: () -> Unit, - onBackCreationSelectionButtonSelected: () -> Unit, - onOptionSelected: (ActiveEntry) -> Unit, - onDisabledProvidersSelected: () -> Unit, - onRemoteEntrySelected: (BaseEntry) -> Unit, + requestDisplayInfo: RequestDisplayInfo, + enabledProviderList: List<EnabledProviderInfo>, + disabledProviderList: List<DisabledProviderInfo>?, + sortedCreateOptionsPairs: List<Pair<CreateOptionInfo, EnabledProviderInfo>>, + hasDefaultProvider: Boolean, + isFromProviderSelection: Boolean, + onBackProviderSelectionButtonSelected: () -> Unit, + onBackCreationSelectionButtonSelected: () -> Unit, + onOptionSelected: (ActiveEntry) -> Unit, + onDisabledProvidersSelected: () -> Unit, + onRemoteEntrySelected: (BaseEntry) -> Unit, + onLog: @Composable (UiEventEnum) -> Unit, ) { SheetContainerCard(topAppBar = { MoreOptionTopAppBar( @@ -381,14 +405,16 @@ fun MoreOptionsSelectionCard( } } } + onLog(CreateCredentialEvent.CREDMAN_CREATE_CRED_MORE_OPTIONS_SELECTION) } @Composable fun MoreOptionsRowIntroCard( - selectedEntry: ActiveEntry, - onIllegalScreenState: (String) -> Unit, - onChangeDefaultSelected: () -> Unit, - onUseOnceSelected: () -> Unit, + selectedEntry: ActiveEntry, + onIllegalScreenState: (String) -> Unit, + onChangeDefaultSelected: () -> Unit, + onUseOnceSelected: () -> Unit, + onLog: @Composable (UiEventEnum) -> Unit, ) { val entryInfo = selectedEntry.activeEntryInfo if (entryInfo !is CreateOptionInfo) { @@ -427,18 +453,20 @@ fun MoreOptionsRowIntroCard( ) } } + onLog(CreateCredentialEvent.CREDMAN_CREATE_CRED_MORE_OPTIONS_ROW_INTRO) } @Composable fun CreationSelectionCard( - requestDisplayInfo: RequestDisplayInfo, - enabledProviderList: List<EnabledProviderInfo>, - providerInfo: EnabledProviderInfo, - createOptionInfo: CreateOptionInfo, - onOptionSelected: (BaseEntry) -> Unit, - onConfirm: () -> Unit, - onMoreOptionsSelected: () -> Unit, - hasDefaultProvider: Boolean, + requestDisplayInfo: RequestDisplayInfo, + enabledProviderList: List<EnabledProviderInfo>, + providerInfo: EnabledProviderInfo, + createOptionInfo: CreateOptionInfo, + onOptionSelected: (BaseEntry) -> Unit, + onConfirm: () -> Unit, + onMoreOptionsSelected: () -> Unit, + hasDefaultProvider: Boolean, + onLog: @Composable (UiEventEnum) -> Unit, ) { SheetContainerCard { item { @@ -524,14 +552,16 @@ fun CreationSelectionCard( item { BodySmallText(text = createOptionInfo.footerDescription) } } } + onLog(CreateCredentialEvent.CREDMAN_CREATE_CRED_CREATION_OPTION_SELECTION) } @Composable fun ExternalOnlySelectionCard( - requestDisplayInfo: RequestDisplayInfo, - activeRemoteEntry: BaseEntry, - onOptionSelected: (BaseEntry) -> Unit, - onConfirm: () -> Unit, + requestDisplayInfo: RequestDisplayInfo, + activeRemoteEntry: BaseEntry, + onOptionSelected: (BaseEntry) -> Unit, + onConfirm: () -> Unit, + onLog: @Composable (UiEventEnum) -> Unit, ) { SheetContainerCard { item { HeadlineIcon(imageVector = Icons.Outlined.QrCodeScanner) } @@ -559,11 +589,13 @@ fun ExternalOnlySelectionCard( ) } } + onLog(CreateCredentialEvent.CREDMAN_CREATE_CRED_EXTERNAL_ONLY_SELECTION) } @Composable fun MoreAboutPasskeysIntroCard( onBackPasskeyIntroButtonSelected: () -> Unit, + onLog: @Composable (UiEventEnum) -> Unit, ) { SheetContainerCard( topAppBar = { @@ -599,6 +631,7 @@ fun MoreAboutPasskeysIntroCard( BodyMediumText(text = stringResource(R.string.seamless_transition_detail)) } } + onLog(CreateCredentialEvent.CREDMAN_CREATE_CRED_MORE_ABOUT_PASSKEYS_INTRO) } @Composable diff --git a/packages/CredentialManager/src/com/android/credentialmanager/logging/CreateCredentialEvent.kt b/packages/CredentialManager/src/com/android/credentialmanager/logging/CreateCredentialEvent.kt new file mode 100644 index 000000000000..daa42be020ce --- /dev/null +++ b/packages/CredentialManager/src/com/android/credentialmanager/logging/CreateCredentialEvent.kt @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2023 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.logging + +import com.android.internal.logging.UiEvent +import com.android.internal.logging.UiEventLogger + +enum class CreateCredentialEvent(private val id: Int) : UiEventLogger.UiEventEnum { + + @UiEvent(doc = "The create credential bottomsheet became visible on the screen.") + CREDMAN_CREATE_CRED_BOTTOMSHEET(1318), + + @UiEvent(doc = "The provider activity is launched on the screen.") + CREDMAN_CREATE_CRED_PROVIDER_ACTIVITY_READY_TO_LAUNCH(1319), + + @UiEvent(doc = "The provider activity is launched and we are waiting for its result. " + + "Contents Hidden.") + CREDMAN_CREATE_CRED_PROVIDER_ACTIVITY_PENDING(1320), + + @UiEvent(doc = "The provider activity is not active or ready launched on the screen.") + CREDMAN_CREATE_CRED_PROVIDER_ACTIVITY_NOT_APPLICABLE(1321), + + @UiEvent(doc = "The passkey introduction card is visible on screen.") + CREDMAN_CREATE_CRED_PASSKEY_INTRO(1322), + + @UiEvent(doc = "The provider selection card is visible on screen.") + CREDMAN_CREATE_CRED_PROVIDER_SELECTION(1323), + + @UiEvent(doc = "The creation option selection card is visible on screen.") + CREDMAN_CREATE_CRED_CREATION_OPTION_SELECTION(1324), + + @UiEvent(doc = "The more option selection card is visible on screen.") + CREDMAN_CREATE_CRED_MORE_OPTIONS_SELECTION(1325), + + @UiEvent(doc = "The more options row intro card is visible on screen.") + CREDMAN_CREATE_CRED_MORE_OPTIONS_ROW_INTRO(1326), + + @UiEvent(doc = "The external only selection card is visible on screen.") + CREDMAN_CREATE_CRED_EXTERNAL_ONLY_SELECTION(1327), + + @UiEvent(doc = "The more about passkeys intro card is visible on screen.") + CREDMAN_CREATE_CRED_MORE_ABOUT_PASSKEYS_INTRO(1328); + + override fun getId(): Int { + return this.id + } +}
\ No newline at end of file diff --git a/packages/CredentialManager/src/com/android/credentialmanager/logging/UIMetrics.kt b/packages/CredentialManager/src/com/android/credentialmanager/logging/UIMetrics.kt new file mode 100644 index 000000000000..4351e8406790 --- /dev/null +++ b/packages/CredentialManager/src/com/android/credentialmanager/logging/UIMetrics.kt @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 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.logging + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import com.android.internal.logging.InstanceId +import com.android.internal.logging.InstanceIdSequence +import com.android.internal.logging.UiEventLogger +import com.android.internal.logging.UiEventLoggerImpl + +class UIMetrics() { + private val INSTANCE_ID_MAX = 1 shl 20 + private val mUiEventLogger: UiEventLogger = UiEventLoggerImpl() + val mInstanceIdSequence: InstanceIdSequence = InstanceIdSequence(INSTANCE_ID_MAX) + + var mInstanceId: InstanceId = mInstanceIdSequence.newInstanceId() + + fun resetInstanceId() { + this.mInstanceId = mInstanceIdSequence.newInstanceId() + } + + @Composable + fun log(event: UiEventLogger.UiEventEnum) { + val instanceId: InstanceId = mInstanceId + LaunchedEffect(true) { + mUiEventLogger.log(event, instanceId) + } + } + + @Composable + fun log(event: UiEventLogger.UiEventEnum, packageName: String) { + val instanceId: InstanceId = mInstanceId + LaunchedEffect(true) { + mUiEventLogger.logWithInstanceId(event, /*uid=*/0, packageName, instanceId) + } + } + + @Composable + fun log(event: UiEventLogger.UiEventEnum, instanceId: InstanceId, packageName: String) { + LaunchedEffect(true) { + mUiEventLogger.logWithInstanceId(event, /*uid=*/0, packageName, instanceId) + } + } +} |