blob: 3d1c0f54650f2393e12bed4b2808911ff331dd96 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/trusted_vault/trusted_vault_histograms.h"
#include <string>
#include "base/metrics/histogram_functions.h"
#include "base/notreached.h"
#include "base/strings/strcat.h"
#include "components/trusted_vault/local_recovery_factor.h"
#include "components/trusted_vault/recovery_key_store_connection.h"
#include "components/trusted_vault/trusted_vault_server_constants.h"
namespace trusted_vault {
namespace {
std::string GetTrustedVaultURLFetchReasonSuffix(
TrustedVaultURLFetchReasonForUMA reason) {
switch (reason) {
case TrustedVaultURLFetchReasonForUMA::kUnspecified:
return std::string();
case TrustedVaultURLFetchReasonForUMA::kRegisterDevice:
return "RegisterDevice";
case TrustedVaultURLFetchReasonForUMA::kRegisterLockScreenKnowledgeFactor:
return "RegisterLockScreenKnowledgeFactor";
case TrustedVaultURLFetchReasonForUMA::kRegisterGpmPin:
return "RegisterGooglePasswordManagerPIN";
case TrustedVaultURLFetchReasonForUMA::
kRegisterUnspecifiedAuthenticationFactor:
return "RegisterUnspecifiedAuthenticationFactor";
case TrustedVaultURLFetchReasonForUMA::kDownloadKeys:
return "DownloadKeys";
case TrustedVaultURLFetchReasonForUMA::kDownloadIsRecoverabilityDegraded:
return "DownloadIsRecoverabilityDegraded";
case TrustedVaultURLFetchReasonForUMA::
kDownloadAuthenticationFactorsRegistrationState:
return "DownloadAuthenticationFactorsRegistrationState";
case TrustedVaultURLFetchReasonForUMA::kRegisterICloudKeychain:
return "RegisterICloudKeychain";
}
NOTREACHED();
}
std::string GetRecoveryKeyStoreURLFetchReasonSuffix(
RecoveryKeyStoreURLFetchReasonForUMA reason) {
switch (reason) {
case RecoveryKeyStoreURLFetchReasonForUMA::kUpdateRecoveryKeyStore:
return "UpdateRecoveryKeyStore";
case RecoveryKeyStoreURLFetchReasonForUMA::kListRecoveryKeyStores:
return "ListRecoveryKeyStores";
}
NOTREACHED();
}
} // namespace
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class SecurityDomainIdOrInvalidForUma {
kInvalid = 0,
kChromeSync = 1,
kPasskeys = 2,
kMaxValue = kPasskeys,
};
SecurityDomainIdOrInvalidForUma GetSecurityDomainIdOrInvalidForUma(
std::optional<SecurityDomainId> security_domain) {
if (!security_domain) {
return SecurityDomainIdOrInvalidForUma::kInvalid;
}
switch (*security_domain) {
case SecurityDomainId::kChromeSync:
return SecurityDomainIdOrInvalidForUma::kChromeSync;
case SecurityDomainId::kPasskeys:
return SecurityDomainIdOrInvalidForUma::kPasskeys;
}
NOTREACHED();
}
void RecordTrustedVaultHintDegradedRecoverabilityChangedReason(
TrustedVaultHintDegradedRecoverabilityChangedReasonForUMA
hint_degraded_recoverability_changed_reason) {
base::UmaHistogramEnumeration(
"TrustedVault.TrustedVaultHintDegradedRecoverabilityChangedReason",
hint_degraded_recoverability_changed_reason);
}
void RecordTrustedVaultDeviceRegistrationState(
TrustedVaultDeviceRegistrationStateForUMA registration_state) {
RecordTrustedVaultRecoveryFactorRegistrationState(
LocalRecoveryFactorType::kPhysicalDevice, SecurityDomainId::kChromeSync,
registration_state);
}
void RecordTrustedVaultRecoveryFactorRegistrationState(
LocalRecoveryFactorType local_recovery_factor_type,
SecurityDomainId security_domain_id,
TrustedVaultRecoveryFactorRegistrationStateForUMA registration_state) {
base::UmaHistogramEnumeration(
base::StrCat(
{"TrustedVault.RecoveryFactorRegistrationState.",
GetLocalRecoveryFactorNameForUma(local_recovery_factor_type), ".",
GetSecurityDomainNameForUma(security_domain_id)}),
registration_state);
}
void RecordTrustedVaultRecoveryFactorRegistrationOutcome(
LocalRecoveryFactorType local_recovery_factor_type,
SecurityDomainId security_domain_id,
TrustedVaultRecoveryFactorRegistrationOutcomeForUMA registration_outcome) {
base::UmaHistogramEnumeration(
base::StrCat(
{"TrustedVault.RecoveryFactorRegistrationOutcome.",
GetLocalRecoveryFactorNameForUma(local_recovery_factor_type), ".",
GetSecurityDomainNameForUma(security_domain_id)}),
registration_outcome);
}
void RecordTrustedVaultURLFetchResponse(SecurityDomainId security_domain_id,
TrustedVaultURLFetchReasonForUMA reason,
int http_response_code,
int net_error) {
CHECK_LE(net_error, 0);
CHECK_GE(http_response_code, 0);
const int value = http_response_code == 0 ? net_error : http_response_code;
const std::string reason_suffix = GetTrustedVaultURLFetchReasonSuffix(reason);
const std::string security_domain_name =
GetSecurityDomainNameForUma(security_domain_id);
base::UmaHistogramSparse("TrustedVault.SecurityDomainServiceURLFetchResponse",
value);
base::UmaHistogramSparse(
base::StrCat({"TrustedVault.SecurityDomainServiceURLFetchResponse", ".",
security_domain_name}),
value);
if (!reason_suffix.empty()) {
base::UmaHistogramSparse(
base::StrCat({"TrustedVault.SecurityDomainServiceURLFetchResponse", ".",
reason_suffix}),
value);
base::UmaHistogramSparse(
base::StrCat({"TrustedVault.SecurityDomainServiceURLFetchResponse", ".",
reason_suffix, ".", security_domain_name}),
value);
}
}
void RecordRecoveryKeyStoreURLFetchResponse(
RecoveryKeyStoreURLFetchReasonForUMA reason,
int http_response_code,
int net_error) {
CHECK_LE(net_error, 0);
CHECK_GE(http_response_code, 0);
const int value = http_response_code == 0 ? net_error : http_response_code;
const std::string reason_suffix =
GetRecoveryKeyStoreURLFetchReasonSuffix(reason);
base::UmaHistogramSparse("TrustedVault.RecoveryKeyStoreURLFetchResponse",
value);
base::UmaHistogramSparse(
base::StrCat({"TrustedVault.RecoveryKeyStoreURLFetchResponse", ".",
reason_suffix}),
value);
}
void RecordRecoveryKeyStoreFetchCertificatesStatus(
RecoveryKeyStoreCertificatesFetchStatusForUMA status) {
base::UmaHistogramEnumeration(
"TrustedVault.RecoveryKeyStoreCertificatesFetchStatus", status);
}
void RecordTrustedVaultDownloadKeysStatus(
LocalRecoveryFactorType local_recovery_factor_type,
SecurityDomainId security_domain_id,
TrustedVaultDownloadKeysStatusForUMA status) {
base::UmaHistogramEnumeration(
base::StrCat(
{"TrustedVault.DownloadKeysStatus.",
GetLocalRecoveryFactorNameForUma(local_recovery_factor_type), ".",
GetSecurityDomainNameForUma(security_domain_id)}),
status);
}
void RecordTrustedVaultDownloadKeysStatus(
TrustedVaultDownloadKeysStatusForUMA status) {
RecordTrustedVaultDownloadKeysStatus(LocalRecoveryFactorType::kPhysicalDevice,
SecurityDomainId::kChromeSync, status);
}
void RecordTrustedVaultRecoverKeysOutcome(
SecurityDomainId security_domain_id,
TrustedVaultRecoverKeysOutcomeForUMA status) {
base::UmaHistogramEnumeration(
base::StrCat({"TrustedVault.RecoverKeysOutcome.",
GetSecurityDomainNameForUma(security_domain_id)}),
status);
}
void RecordTrustedVaultFileReadStatus(SecurityDomainId security_domain_id,
TrustedVaultFileReadStatusForUMA status) {
base::UmaHistogramEnumeration(
"TrustedVault.FileReadStatus." +
GetSecurityDomainNameForUma(security_domain_id),
status);
}
void RecordTrustedVaultSetEncryptionKeysForSecurityDomain(
std::optional<SecurityDomainId> security_domain,
IsOffTheRecord is_off_the_record) {
SecurityDomainIdOrInvalidForUma domain_for_uma =
GetSecurityDomainIdOrInvalidForUma(security_domain);
base::UmaHistogramEnumeration(
"TrustedVault.SetEncryptionKeysForSecurityDomain."
"AllProfiles",
domain_for_uma);
if (is_off_the_record == IsOffTheRecord::kYes) {
base::UmaHistogramEnumeration(
"TrustedVault.SetEncryptionKeysForSecurityDomain.OffTheRecordOnly",
domain_for_uma);
}
}
void RecordCallToJsSetClientEncryptionKeysWithSecurityDomainToUma(
std::optional<SecurityDomainId> security_domain) {
SecurityDomainIdOrInvalidForUma domain_for_uma =
GetSecurityDomainIdOrInvalidForUma(security_domain);
base::UmaHistogramEnumeration(
"TrustedVault.JavascriptSetClientEncryptionKeysForSecurityDomain",
domain_for_uma);
}
void RecordTrustedVaultListSecurityDomainMembersPinStatus(
SecurityDomainId security_domain_id,
TrustedVaultListSecurityDomainMembersPinStatus status) {
base::UmaHistogramEnumeration(
"TrustedVault.ListSecurityDomainMembersPinStatus." +
GetSecurityDomainNameForUma(security_domain_id),
status);
}
std::string GetLocalRecoveryFactorNameForUma(
LocalRecoveryFactorType local_recovery_factor_type) {
// These strings get embedded in histogram names and so should not be
// changed.
switch (local_recovery_factor_type) {
case LocalRecoveryFactorType::kPhysicalDevice:
return "PhysicalDevice";
#if BUILDFLAG(IS_MAC)
case LocalRecoveryFactorType::kICloudKeychain:
return "ICloudKeychain";
#endif
// If adding a new value, also update the variants for
// LocalRecoveryFactorType in
// tools/metrics/histograms/metadata/trusted_vault/histograms.xml.
}
}
std::string GetSecurityDomainNameForUma(SecurityDomainId domain) {
switch (domain) {
// These strings get embedded in histogram names and so should not be
// changed.
case SecurityDomainId::kChromeSync:
return "ChromeSync";
case SecurityDomainId::kPasskeys:
return "HwProtected";
// If adding a new value, also update the variants for SecurityDomainId
// in tools/metrics/histograms/metadata/trusted_vault/histograms.xml.
}
}
} // namespace trusted_vault