1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SYNC_SERVICE_SYNC_SESSION_DURATIONS_METRICS_RECORDER_H_
#define COMPONENTS_SYNC_SERVICE_SYNC_SESSION_DURATIONS_METRICS_RECORDER_H_
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "base/timer/elapsed_timer.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/sync/service/history_sync_session_durations_metrics_recorder.h"
#include "components/sync/service/sync_service.h"
#include "components/sync/service/sync_service_observer.h"
namespace syncer {
// Tracks the active browsing time that the user spends signed in and/or syncing
// as fraction of their total browsing time.
class SyncSessionDurationsMetricsRecorder
: public syncer::SyncServiceObserver,
public signin::IdentityManager::Observer {
public:
enum class SigninStatus { kSignedIn, kSignedInWithError, kSignedOut };
// Callers must ensure that the parameters outlive this object.
SyncSessionDurationsMetricsRecorder(
SyncService* sync_service,
signin::IdentityManager* identity_manager);
SyncSessionDurationsMetricsRecorder(
const SyncSessionDurationsMetricsRecorder&) = delete;
SyncSessionDurationsMetricsRecorder& operator=(
const SyncSessionDurationsMetricsRecorder&) = delete;
~SyncSessionDurationsMetricsRecorder() override;
// Returns whether the user is signed in.
SigninStatus GetSigninStatus() const;
// Returns whether the user is syncing.
// Note: this is not the same as `sync_status_`.
// `sync_status_` says ON (kind of like saying "yes, syncing") even if
// syncing is paused because the user signed out (i.e., the account is in an
// error state). IsSyncing() returns false in those cases.
bool IsSyncing() const;
// Informs this service that a session started at `session_start` time.
void OnSessionStarted(base::TimeTicks session_start);
void OnSessionEnded(base::TimeDelta session_length);
// syncer::SyncServiceObserver:
void OnStateChanged(syncer::SyncService* sync) override;
// IdentityManager::Observer:
void OnPrimaryAccountChanged(
const signin::PrimaryAccountChangeEvent& event) override;
void OnRefreshTokenUpdatedForAccount(
const CoreAccountInfo& account_info) override;
void OnRefreshTokenRemovedForAccount(
const CoreAccountId& account_id) override;
void OnRefreshTokensLoaded() override;
void OnErrorStateOfRefreshTokenUpdatedForAccount(
const CoreAccountInfo& account_info,
const GoogleServiceAuthError& error,
signin_metrics::SourceForRefreshTokenOperation token_operation_source)
override;
void OnAccountsInCookieUpdated(
const signin::AccountsInCookieJarInfo& accounts_in_cookie_jar_info,
const GoogleServiceAuthError& error) override;
void OnIdentityManagerShutdown(
signin::IdentityManager* identity_manager) override;
private:
// The state the feature is in. The state starts as UNKNOWN. After it moves
// out of UNKNOWN, it can alternate between OFF and ON.
enum class FeatureState { UNKNOWN, OFF, ON };
// Helper function for pattern matching on the product of two enums.
static constexpr int GetFeatureStates(SigninStatus signin_status,
FeatureState sync_status);
void LogSigninDuration(base::TimeDelta session_length);
void LogSyncAndAccountDuration(base::TimeDelta session_length);
bool ShouldLogUpdate(FeatureState new_sync_status,
SigninStatus new_signin_status);
void UpdateSyncAndAccountStatus(FeatureState new_sync_status,
SigninStatus new_signin_status);
void HandleSyncAndAccountChange();
// Determines the signin status.
SigninStatus DetermineSigninStatus() const;
// Determines the sync status.
FeatureState DetermineSyncStatus() const;
const raw_ptr<SyncService> sync_service_;
const raw_ptr<signin::IdentityManager> identity_manager_;
HistorySyncSessionDurationsMetricsRecorder history_sync_recorder_;
base::ScopedObservation<syncer::SyncService, syncer::SyncServiceObserver>
sync_observation_{this};
base::ScopedObservation<signin::IdentityManager,
signin::IdentityManager::Observer>
identity_manager_observation_{this};
// Tracks the elapsed active session time while the browser is open. The timer
// is absent if there's no active session.
std::unique_ptr<base::ElapsedTimer> total_session_timer_;
// Whether there is a signed in account in Gaia cookies.
FeatureState cookie_signin_status_ = FeatureState::UNKNOWN;
// Tracks the elapsed active session time in the current signin status. The
// timer is absent if there's no active session.
std::unique_ptr<base::ElapsedTimer> signin_session_timer_;
// Whether Chrome currently has a primary account and whether its token is
// valid.
SigninStatus signin_status_ = SigninStatus::kSignedOut;
// Whether or not sync is currently active. Sync is considered to be ON even
// when paused.
FeatureState sync_status_ = FeatureState::UNKNOWN;
// Tracks the elapsed active session time in the current sync and account
// status. The timer is absent if there's no active session.
std::unique_ptr<base::ElapsedTimer> sync_account_session_timer_;
};
} // namespace syncer
#endif // COMPONENTS_SYNC_SERVICE_SYNC_SESSION_DURATIONS_METRICS_RECORDER_H_
|