| // Copyright 2020 The Chromium Authors. All rights reserved. | 
 | // 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/bind.h" | 
 | #include "base/logging.h" | 
 | #include "base/metrics/histogram_functions.h" | 
 | #include "chrome/browser/ash/profiles/profile_helper.h" | 
 | #include "chrome/browser/profiles/profile.h" | 
 | #include "chrome/browser/signin/identity_manager_factory.h" | 
 | #include "components/session_manager/core/session_manager.h" | 
 | #include "components/signin/public/identity_manager/consent_level.h" | 
 | #include "components/signin/public/identity_manager/identity_manager.h" | 
 | #include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h" | 
 | #include "components/signin/public/identity_manager/scope_set.h" | 
 | #include "components/user_manager/user.h" | 
 | #include "components/user_manager/user_manager.h" | 
 | #include "google_apis/gaia/oauth2_id_token_decoder.h" | 
 |  | 
 | namespace { | 
 |  | 
 | constexpr char kHistogramName[] = "ChromeOS.FamilyLinkUser.LogSegment"; | 
 |  | 
 | }  // namespace | 
 |  | 
 | FamilyLinkUserMetricsProvider::FamilyLinkUserMetricsProvider() { | 
 |   session_manager::SessionManager* session_manager = | 
 |       session_manager::SessionManager::Get(); | 
 |   // The |session_manager| is nullptr only for unit tests. | 
 |   if (session_manager) | 
 |     session_manager->AddObserver(this); | 
 | } | 
 |  | 
 | FamilyLinkUserMetricsProvider::~FamilyLinkUserMetricsProvider() { | 
 |   session_manager::SessionManager* session_manager = | 
 |       session_manager::SessionManager::Get(); | 
 |   // The |session_manager| is nullptr only for unit tests. | 
 |   if (session_manager) | 
 |     session_manager->RemoveObserver(this); | 
 | } | 
 |  | 
 | // This function is called at unpredictable intervals throughout the entire | 
 | // ChromeOS session, so guarantee it will never crash. | 
 | void FamilyLinkUserMetricsProvider::ProvideCurrentSessionData( | 
 |     metrics::ChromeUserMetricsExtension* uma_proto_unused) { | 
 |   if (!log_segment_) | 
 |     return; | 
 |   base::UmaHistogramEnumeration(kHistogramName, log_segment_.value()); | 
 | } | 
 |  | 
 | void FamilyLinkUserMetricsProvider::OnUserSessionStarted(bool is_primary_user) { | 
 |   if (!is_primary_user) | 
 |     return; | 
 |  | 
 |   const user_manager::User* primary_user = | 
 |       user_manager::UserManager::Get()->GetPrimaryUser(); | 
 |   DCHECK(primary_user); | 
 |   if (!primary_user->IsChild()) { | 
 |     SetLogSegment(LogSegment::kOther); | 
 |     return; | 
 |   } | 
 |  | 
 |   DCHECK(primary_user->is_profile_created()); | 
 |   Profile* profile = | 
 |       chromeos::ProfileHelper::Get()->GetProfileByUser(primary_user); | 
 |   DCHECK(profile); | 
 |   DCHECK(chromeos::ProfileHelper::IsRegularProfile(profile)); | 
 |  | 
 |   signin::IdentityManager* identity_manager = | 
 |       IdentityManagerFactory::GetForProfile(profile); | 
 |   DCHECK(identity_manager); | 
 |  | 
 |   DCHECK(!access_token_fetcher_); | 
 |   access_token_fetcher_ = | 
 |       std::make_unique<signin::PrimaryAccountAccessTokenFetcher>( | 
 |           /*consumer_name=*/"FamilyLinkUserMetricsProvider", identity_manager, | 
 |           signin::ScopeSet(), | 
 |           base::BindOnce( | 
 |               &FamilyLinkUserMetricsProvider::OnAccessTokenRequestCompleted, | 
 |               // It is safe to use base::Unretained as |this| owns | 
 |               // |access_token_fetcher_|. See comments in | 
 |               // primary_account_access_token_fetcher.h. | 
 |               base::Unretained(this)), | 
 |           signin::PrimaryAccountAccessTokenFetcher::Mode::kImmediate, | 
 |           signin::ConsentLevel::kSignin); | 
 | } | 
 |  | 
 | // static | 
 | const char* FamilyLinkUserMetricsProvider::GetHistogramNameForTesting() { | 
 |   return kHistogramName; | 
 | } | 
 |  | 
 | void FamilyLinkUserMetricsProvider::SetLogSegment(LogSegment log_segment) { | 
 |   log_segment_ = log_segment; | 
 | } | 
 |  | 
 | void FamilyLinkUserMetricsProvider::OnAccessTokenRequestCompleted( | 
 |     GoogleServiceAuthError error, | 
 |     signin::AccessTokenInfo access_token_info) { | 
 |   access_token_fetcher_.reset(); | 
 |  | 
 |   if (error.state() != GoogleServiceAuthError::NONE) | 
 |     return; | 
 |  | 
 |   gaia::TokenServiceFlags service_flags = | 
 |       gaia::ParseServiceFlags(access_token_info.id_token); | 
 |   LogSegment log_segment = service_flags.is_child_account | 
 |                                ? LogSegment::kUnderConsentAge | 
 |                                : LogSegment::kOverConsentAge; | 
 |   SetLogSegment(log_segment); | 
 | } |