Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: components/sync_driver/startup_controller.cc

Issue 2203673002: [Sync] Move //components/sync_driver to //components/sync/driver. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@sd-a
Patch Set: Full change rebased on static lib. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/sync_driver/startup_controller.h"
6
7 #include <string>
8
9 #include "base/command_line.h"
10 #include "base/location.h"
11 #include "base/metrics/histogram.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "components/sync_driver/sync_driver_switches.h"
16 #include "components/sync_driver/sync_prefs.h"
17
18 namespace browser_sync {
19
20 namespace {
21
22 // The amount of time we'll wait to initialize sync if no data type triggers
23 // initialization via a StartSyncFlare.
24 const int kDeferredInitFallbackSeconds = 10;
25
26 // Enum (for UMA, primarily) defining different events that cause us to
27 // exit the "deferred" state of initialization and invoke start_backend.
28 enum DeferredInitTrigger {
29 // We have received a signal from a SyncableService requesting that sync
30 // starts as soon as possible.
31 TRIGGER_DATA_TYPE_REQUEST,
32 // No data type requested sync to start and our fallback timer expired.
33 TRIGGER_FALLBACK_TIMER,
34 MAX_TRIGGER_VALUE
35 };
36
37 } // namespace
38
39 StartupController::StartupController(const sync_driver::SyncPrefs* sync_prefs,
40 base::Callback<bool()> can_start,
41 base::Closure start_backend)
42 : bypass_setup_complete_(false),
43 received_start_request_(false),
44 setup_in_progress_(false),
45 sync_prefs_(sync_prefs),
46 can_start_(can_start),
47 start_backend_(start_backend),
48 fallback_timeout_(
49 base::TimeDelta::FromSeconds(kDeferredInitFallbackSeconds)),
50 weak_factory_(this) {
51 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
52 switches::kSyncDeferredStartupTimeoutSeconds)) {
53 int timeout = kDeferredInitFallbackSeconds;
54 if (base::StringToInt(
55 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
56 switches::kSyncDeferredStartupTimeoutSeconds),
57 &timeout)) {
58 DCHECK_GE(timeout, 0);
59 DVLOG(2) << "Sync StartupController overriding startup timeout to "
60 << timeout << " seconds.";
61 fallback_timeout_ = base::TimeDelta::FromSeconds(timeout);
62 }
63 }
64 }
65
66 StartupController::~StartupController() {}
67
68 void StartupController::Reset(const syncer::ModelTypeSet registered_types) {
69 received_start_request_ = false;
70 bypass_setup_complete_ = false;
71 start_up_time_ = base::Time();
72 start_backend_time_ = base::Time();
73 // Don't let previous timers affect us post-reset.
74 weak_factory_.InvalidateWeakPtrs();
75 registered_types_ = registered_types;
76 }
77
78 void StartupController::SetSetupInProgress(bool setup_in_progress) {
79 setup_in_progress_ = setup_in_progress;
80 if (setup_in_progress_) {
81 TryStart();
82 }
83 }
84
85 bool StartupController::StartUp(StartUpDeferredOption deferred_option) {
86 const bool first_start = start_up_time_.is_null();
87 if (first_start)
88 start_up_time_ = base::Time::Now();
89
90 if (deferred_option == STARTUP_BACKEND_DEFERRED &&
91 !base::CommandLine::ForCurrentProcess()->HasSwitch(
92 switches::kSyncDisableDeferredStartup) &&
93 sync_prefs_->GetPreferredDataTypes(registered_types_)
94 .Has(syncer::SESSIONS)) {
95 if (first_start) {
96 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
97 FROM_HERE,
98 base::Bind(&StartupController::OnFallbackStartupTimerExpired,
99 weak_factory_.GetWeakPtr()),
100 fallback_timeout_);
101 }
102 return false;
103 }
104
105 if (start_backend_time_.is_null()) {
106 start_backend_time_ = base::Time::Now();
107 start_backend_.Run();
108 }
109
110 return true;
111 }
112
113 void StartupController::OverrideFallbackTimeoutForTest(
114 const base::TimeDelta& timeout) {
115 fallback_timeout_ = timeout;
116 }
117
118 bool StartupController::TryStart() {
119 if (!can_start_.Run())
120 return false;
121
122 // For performance reasons, defer the heavy lifting for sync init unless:
123 //
124 // - a datatype has requested an immediate start of sync, or
125 // - sync needs to start up the backend immediately to provide control state
126 // and encryption information to the UI.
127 // Do not start up the sync backend if setup has not completed and isn't
128 // in progress, unless told to otherwise.
129 if (setup_in_progress_) {
130 return StartUp(STARTUP_IMMEDIATE);
131 } else if (sync_prefs_->IsFirstSetupComplete() || bypass_setup_complete_) {
132 return StartUp(received_start_request_ ? STARTUP_IMMEDIATE
133 : STARTUP_BACKEND_DEFERRED);
134 } else {
135 return false;
136 }
137 }
138
139 bool StartupController::TryStartImmediately() {
140 received_start_request_ = true;
141 bypass_setup_complete_ = true;
142 return TryStart();
143 }
144
145 void StartupController::RecordTimeDeferred() {
146 DCHECK(!start_up_time_.is_null());
147 base::TimeDelta time_deferred = base::Time::Now() - start_up_time_;
148 UMA_HISTOGRAM_CUSTOM_TIMES("Sync.Startup.TimeDeferred2",
149 time_deferred,
150 base::TimeDelta::FromSeconds(0),
151 base::TimeDelta::FromMinutes(2),
152 60);
153 }
154
155 void StartupController::OnFallbackStartupTimerExpired() {
156 DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(
157 switches::kSyncDisableDeferredStartup));
158
159 if (!start_backend_time_.is_null())
160 return;
161
162 DVLOG(2) << "Sync deferred init fallback timer expired, starting backend.";
163 RecordTimeDeferred();
164 UMA_HISTOGRAM_ENUMERATION("Sync.Startup.DeferredInitTrigger",
165 TRIGGER_FALLBACK_TIMER,
166 MAX_TRIGGER_VALUE);
167 received_start_request_ = true;
168 TryStart();
169 }
170
171 std::string StartupController::GetBackendInitializationStateString() const {
172 if (!start_backend_time_.is_null())
173 return "Started";
174 else if (!start_up_time_.is_null())
175 return "Deferred";
176 else
177 return "Not started";
178 }
179
180 void StartupController::OnDataTypeRequestsSyncStartup(syncer::ModelType type) {
181 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
182 switches::kSyncDisableDeferredStartup)) {
183 DVLOG(2) << "Ignoring data type request for sync startup: "
184 << syncer::ModelTypeToString(type);
185 return;
186 }
187
188 if (!start_backend_time_.is_null())
189 return;
190
191 DVLOG(2) << "Data type requesting sync startup: "
192 << syncer::ModelTypeToString(type);
193 // Measure the time spent waiting for init and the type that triggered it.
194 // We could measure the time spent deferred on a per-datatype basis, but
195 // for now this is probably sufficient.
196 if (!start_up_time_.is_null()) {
197 RecordTimeDeferred();
198 UMA_HISTOGRAM_ENUMERATION("Sync.Startup.TypeTriggeringInit",
199 ModelTypeToHistogramInt(type),
200 syncer::MODEL_TYPE_COUNT);
201 UMA_HISTOGRAM_ENUMERATION("Sync.Startup.DeferredInitTrigger",
202 TRIGGER_DATA_TYPE_REQUEST,
203 MAX_TRIGGER_VALUE);
204 }
205 received_start_request_ = true;
206 TryStart();
207 }
208
209 } // namespace browser_sync
OLDNEW
« no previous file with comments | « components/sync_driver/startup_controller.h ('k') | components/sync_driver/startup_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698