blob: d039d17f612a397b25cb1c1b1d99f7c527cca32c [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/metrics/family_link_user_metrics_provider.h"
#include "base/metrics/histogram_functions.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "components/session_manager/core/session_manager.h"
namespace {
constexpr char kFamilyLinkUserLogSegmentHistogramName[] =
"FamilyLinkUser.LogSegment";
bool AreParentalSupervisionCapabilitiesKnown(
const AccountCapabilities& capabilities) {
return capabilities.can_stop_parental_supervision() !=
signin::Tribool::kUnknown &&
capabilities.is_subject_to_parental_controls() !=
signin::Tribool::kUnknown;
}
} // namespace
FamilyLinkUserMetricsProvider::FamilyLinkUserMetricsProvider() {
auto* factory = IdentityManagerFactory::GetInstance();
if (factory)
scoped_factory_observation_.Observe(factory);
}
FamilyLinkUserMetricsProvider::~FamilyLinkUserMetricsProvider() = default;
void FamilyLinkUserMetricsProvider::ProvideCurrentSessionData(
metrics::ChromeUserMetricsExtension* uma_proto_unused) {
// This function is called at unpredictable intervals throughout the Chrome
// session, so guarantee it will never crash.
if (!log_segment_)
return;
base::UmaHistogramEnumeration(kFamilyLinkUserLogSegmentHistogramName,
log_segment_.value());
}
void FamilyLinkUserMetricsProvider::IdentityManagerCreated(
signin::IdentityManager* identity_manager) {
CHECK(identity_manager);
DCHECK(!identity_manager_);
identity_manager_ = identity_manager;
scoped_observation_.Observe(identity_manager_);
// The account may have been updated before registering the observer.
// Set the log segment to the primary account info if it exists.
AccountInfo primary_account_info = identity_manager_->FindExtendedAccountInfo(
identity_manager_->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin));
if (!primary_account_info.IsEmpty())
OnExtendedAccountInfoUpdated(primary_account_info);
}
void FamilyLinkUserMetricsProvider::OnPrimaryAccountChanged(
const signin::PrimaryAccountChangeEvent& event_details) {
signin::PrimaryAccountChangeEvent::Type event_type =
event_details.GetEventTypeFor(signin::ConsentLevel::kSignin);
switch (event_type) {
case signin::PrimaryAccountChangeEvent::Type::kNone: {
break;
}
case signin::PrimaryAccountChangeEvent::Type::kSet: {
DCHECK(identity_manager_);
AccountInfo account_info = identity_manager_->FindExtendedAccountInfo(
event_details.GetCurrentState().primary_account);
OnExtendedAccountInfoUpdated(account_info);
break;
}
case signin::PrimaryAccountChangeEvent::Type::kCleared: {
// Reset the log segment if the user signs out during the session.
log_segment_.reset();
break;
}
}
}
void FamilyLinkUserMetricsProvider::OnIdentityManagerShutdown(
signin::IdentityManager* identity_manager) {
DCHECK_EQ(identity_manager, identity_manager_);
identity_manager_ = nullptr;
scoped_observation_.Reset();
}
void FamilyLinkUserMetricsProvider::OnExtendedAccountInfoUpdated(
const AccountInfo& account_info) {
if (identity_manager_->GetPrimaryAccountId(signin::ConsentLevel::kSignin) !=
account_info.account_id) {
// Only record extended account information associated with the primary
// account of the profile.
return;
}
if (!AreParentalSupervisionCapabilitiesKnown(account_info.capabilities)) {
// Because account info is fetched asynchronously it is possible for a
// subset of the info to be updated that does not include account
// capabilities. Only log metrics after the capability fetch completes.
return;
}
auto is_subject_to_parental_controls =
account_info.capabilities.is_subject_to_parental_controls();
if (is_subject_to_parental_controls == signin::Tribool::kTrue) {
auto can_stop_supervision =
account_info.capabilities.can_stop_parental_supervision();
if (can_stop_supervision == signin::Tribool::kTrue) {
// Log as a supervised user that has chosen to enable parental
// supervision on their account, e.g. Geller accounts.
SetLogSegment(LogSegment::kSupervisionEnabledByUser);
} else {
// Log as a supervised user that has parental supervision enabled
// by a policy applied to their account, e.g. Unicorn accounts.
SetLogSegment(LogSegment::kSupervisionEnabledByPolicy);
}
} else {
// Log as unsupervised user if the account is not subject to parental
// controls.
SetLogSegment(LogSegment::kUnsupervised);
}
}
// static
const char* FamilyLinkUserMetricsProvider::GetHistogramNameForTesting() {
return kFamilyLinkUserLogSegmentHistogramName;
}
void FamilyLinkUserMetricsProvider::SetLogSegment(LogSegment log_segment) {
log_segment_ = log_segment;
}