Commit 783eade5 authored by Ramin Halavati's avatar Ramin Halavati Committed by Chromium LUCI CQ

Add metric for lifetime of Guest profiles when signin token transferred

Adds "Profile.Guest.SigninTransferred.Lifetime" and
"Profile.Guest.BlankState.Lifetime" for comparison of Guest
profile lifetime when its initialized by a signed in token and when it
starts from blank state.

Bug: 1157764
Change-Id: Iea3a8cce12bddd8fed19b9a1c01c7c8c4c68dd2f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2623009Reviewed-by: default avatarAlex Ilin <alexilin@chromium.org>
Reviewed-by: default avatarDavid Roger <droger@chromium.org>
Commit-Queue: Ramin Halavati <rhalavati@chromium.org>
Cr-Commit-Position: refs/heads/master@{#843068}
parent be4d3a70
......@@ -977,6 +977,8 @@ IN_PROC_BROWSER_TEST_P(GuestProfileLifetimeBrowserTest, UnderOneMinute) {
is_ephemeral() ? 0 : 1);
tester.ExpectUniqueSample("Profile.Guest.Ephemeral.Lifetime", 0,
is_ephemeral() ? 1 : 0);
tester.ExpectUniqueSample("Profile.Guest.BlankState.Lifetime", 0, 1);
// TODO(https://crbug.com/1157764): Add test for |SigninTransferred| case.
}
IN_PROC_BROWSER_TEST_P(GuestProfileLifetimeBrowserTest, OneHour) {
......@@ -992,6 +994,8 @@ IN_PROC_BROWSER_TEST_P(GuestProfileLifetimeBrowserTest, OneHour) {
is_ephemeral() ? 0 : 1);
tester.ExpectUniqueSample("Profile.Guest.Ephemeral.Lifetime", 60,
is_ephemeral() ? 1 : 0);
tester.ExpectUniqueSample("Profile.Guest.BlankState.Lifetime", 60, 1);
// TODO(https://crbug.com/1157764): Add test for |SigninTransferred| case.
}
INSTANTIATE_TEST_SUITE_P(AllGuestTypes,
......
......@@ -161,6 +161,10 @@
#include "chrome/browser/signin/signin_util_win.h"
#endif // defined(OS_WIN) && BUILDFLAG(ENABLE_DICE_SUPPORT)
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
#include "chrome/browser/signin/dice_signed_in_profile_creator.h"
#endif // #if BUILDFLAG(ENABLE_DICE_SUPPORT)
using base::UserMetricsAction;
using content::BrowserThread;
......@@ -368,6 +372,15 @@ bool IsEphemeral(Profile* profile) {
profile->IsEphemeralGuestProfile();
}
#if !defined(OS_ANDROID)
void RecordGuestProfileLifetime(const std::string& histogram_name,
base::TimeDelta duration) {
base::UmaHistogramCustomCounts(histogram_name, duration.InMinutes(), 1,
base::TimeDelta::FromDays(28).InMinutes(),
100);
}
#endif // !defined(OS_ANDROID)
} // namespace
ProfileManager::ProfileManager(const base::FilePath& user_data_dir)
......@@ -2024,14 +2037,20 @@ void ProfileManager::OnBrowserClosed(Browser* browser) {
if (profile->IsGuestSession() || profile->IsEphemeralGuestProfile()) {
auto duration = base::Time::Now() - profile->GetCreationTime();
if (profile->IsEphemeralGuestProfile()) {
base::UmaHistogramCustomCounts(
"Profile.Guest.Ephemeral.Lifetime", duration.InMinutes(), 1,
base::TimeDelta::FromDays(28).InMinutes(), 100);
RecordGuestProfileLifetime("Profile.Guest.Ephemeral.Lifetime", duration);
} else {
RecordGuestProfileLifetime("Profile.Guest.OTR.Lifetime", duration);
}
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
if (DiceSignedInProfileCreator::GuestSigninTokenTransferredUserData::Get(
profile)) {
RecordGuestProfileLifetime("Profile.Guest.SigninTransferred.Lifetime",
duration);
} else {
base::UmaHistogramCustomCounts(
"Profile.Guest.OTR.Lifetime", duration.InMinutes(), 1,
base::TimeDelta::FromDays(28).InMinutes(), 100);
RecordGuestProfileLifetime("Profile.Guest.BlankState.Lifetime", duration);
}
#endif // BUILDFLAG(ENABLE_DICE_SUPPORT)
CleanUpGuestProfile();
}
......
......@@ -52,6 +52,10 @@ class DiceSignedInProfileCreatorShutdownNotifierFactory
} // namespace
const void* const
DiceSignedInProfileCreator::kGuestSigninTokenTransferredUserDataKey =
&DiceSignedInProfileCreator::kGuestSigninTokenTransferredUserDataKey;
// Waits until the tokens are loaded and calls the callback. The callback is
// called immediately if the tokens are already loaded, and called with nullptr
// if the profile is destroyed before the tokens are loaded.
......@@ -245,6 +249,8 @@ void DiceSignedInProfileCreator::OnNewProfileTokensLoaded(
auto* new_profile_accounts_mutator =
IdentityManagerFactory::GetForProfile(new_profile)->GetAccountsMutator();
accounts_mutator->MoveAccount(new_profile_accounts_mutator, account_id_);
if (new_profile->IsEphemeralGuestProfile())
GuestSigninTokenTransferredUserData::Set(new_profile);
if (callback_)
std::move(callback_).Run(new_profile);
}
......@@ -19,6 +19,25 @@ class TokensLoadedCallbackRunner;
// Extracts an account from an existing profile and moves it to a new profile.
class DiceSignedInProfileCreator {
public:
// Empty user data, attached to the profile if this is a guest profile and a
// signin token was transferred.
class GuestSigninTokenTransferredUserData
: public base::SupportsUserData::Data {
public:
GuestSigninTokenTransferredUserData() = default;
static void Set(Profile* profile) {
profile->SetUserData(
kGuestSigninTokenTransferredUserDataKey,
std::make_unique<GuestSigninTokenTransferredUserData>());
}
static bool Get(Profile* profile) {
return profile->GetUserData(kGuestSigninTokenTransferredUserDataKey);
}
private:
DISALLOW_COPY_AND_ASSIGN(GuestSigninTokenTransferredUserData);
};
// Creates a new profile or uses Guest profile if |use_guest_profile|, and
// moves the account from source_profile to it.
// The callback is called with the new profile or nullptr in case of failure.
......@@ -47,6 +66,9 @@ class DiceSignedInProfileCreator {
DiceSignedInProfileCreator& operator=(const DiceSignedInProfileCreator&) =
delete;
// Key for GuestSigninTokenTransferredUserDataKey.
static const void* const kGuestSigninTokenTransferredUserDataKey;
private:
// Callback invoked once a profile is created, so we can transfer the
// credentials.
......
......@@ -212,12 +212,18 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
<owner>rhalavati@chromium.org</owner>
<owner>chrome-privacy-core@google.com</owner>
<summary>
This histogram records the lifetime duration of {Type} Guest profiles. It is
recorded once the profile for an {Type} Guest session is closed.
This histogram records the lifetime duration of {Type}. It is recorded once
the profile for the Guest session is closed.
</summary>
<token key="Type">
<variant name="Ephemeral"/>
<variant name="OTR"/>
<variant name="BlankState"
summary="a Guest profile where the session is initialized in blank
state"/>
<variant name="Ephemeral" summary="an Ephemeral Guest profile"/>
<variant name="OTR" summary="an off-the-record Guest profile"/>
<variant name="SigninTransferred"
summary="a Guest profile to which a sign-in token has been
transferred"/>
</token>
</histogram>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment