File: sync_startup_tracker.cc

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (109 lines) | stat: -rw-r--r-- 3,540 bytes parent folder | download | duplicates (4)
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
// Copyright 2013 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/sync/sync_startup_tracker.h"

#include <optional>

#include "base/functional/bind.h"
#include "base/notreached.h"
#include "components/sync/service/sync_service.h"

namespace {

constexpr base::TimeDelta kDefaultWaitTimeout = base::Seconds(10);

std::optional<base::TimeDelta> g_wait_timeout = kDefaultWaitTimeout;

}  // namespace

SyncStartupTracker::SyncStartupTracker(syncer::SyncService* sync_service,
                                       SyncStartupStateChangedCallback callback)
    : sync_service_(sync_service),
      sync_startup_status_changed_callback_(std::move(callback)) {
  DCHECK(sync_service_);
  sync_service_observation_.Observe(sync_service_);
  if (g_wait_timeout.has_value()) {
    timeout_waiter_.Start(FROM_HERE, g_wait_timeout.value(),
                          base::BindOnce(&SyncStartupTracker::OnStartupTimeout,
                                         weak_factory_.GetWeakPtr()));
  }

  CheckServiceState();
}

SyncStartupTracker::~SyncStartupTracker() = default;

void SyncStartupTracker::OnStateChanged(syncer::SyncService* sync) {
  CheckServiceState();
}

void SyncStartupTracker::OnStartupTimeout() {
  is_timed_out_ = true;
  CheckServiceState();
}

void SyncStartupTracker::CheckServiceState() {
  ServiceStartupState state = GetServiceStartupState(sync_service_);
  if (state == ServiceStartupState::kPending) {
    if (is_timed_out_) {
      state = ServiceStartupState::kTimeout;
    } else {
      // Do nothing - still waiting for sync to finish starting up.
      return;
    }
  }

  timeout_waiter_.Stop();
  sync_service_observation_.Reset();

  DCHECK(sync_startup_status_changed_callback_);
  std::move(sync_startup_status_changed_callback_).Run(state);
}

// static
SyncStartupTracker::ServiceStartupState
SyncStartupTracker::GetServiceStartupState(syncer::SyncService* sync_service) {
  // If no service exists or it can't be started, treat as a startup error.
  if (!sync_service || !sync_service->CanSyncFeatureStart()) {
    return ServiceStartupState::kError;
  }

  // Unrecoverable errors return false for CanSyncFeatureStart(), handled above.
  DCHECK(!sync_service->HasUnrecoverableError());

  switch (sync_service->GetTransportState()) {
    case syncer::SyncService::TransportState::DISABLED:
      NOTREACHED();
    case syncer::SyncService::TransportState::START_DEFERRED:
    case syncer::SyncService::TransportState::INITIALIZING:
      // No error detected yet, but the sync engine hasn't started up yet, so
      // we're in the pending state.
      return ServiceStartupState::kPending;
    case syncer::SyncService::TransportState::PAUSED:
      // Persistent auth errors lead to sync pausing.
      return ServiceStartupState::kError;
    case syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION:
    case syncer::SyncService::TransportState::CONFIGURING:
    case syncer::SyncService::TransportState::ACTIVE:
      DCHECK(sync_service->IsEngineInitialized());
      return ServiceStartupState::kComplete;
  }

  NOTREACHED();
}

namespace testing {

ScopedSyncStartupTimeoutOverride::ScopedSyncStartupTimeoutOverride(
    std::optional<base::TimeDelta> wait_timeout) {
  old_wait_timeout_ = g_wait_timeout;
  g_wait_timeout = wait_timeout;
}

ScopedSyncStartupTimeoutOverride::~ScopedSyncStartupTimeoutOverride() {
  g_wait_timeout = old_wait_timeout_;
}

}  // namespace testing