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

Side by Side Diff: chrome/browser/sync/startup_controller.cc

Issue 162443004: sync: final pieces to sync deferred initialization (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review Created 6 years, 10 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 | Annotate | Revision Log
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 "chrome/browser/sync/startup_controller.h"
6
7 #include "base/command_line.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/metrics/histogram.h"
10 #include "chrome/browser/managed_mode/managed_user_signin_manager_wrapper.h"
11 #include "chrome/browser/signin/profile_oauth2_token_service.h"
12 #include "chrome/browser/sync/sync_prefs.h"
13 #include "chrome/common/chrome_switches.h"
14
15 namespace browser_sync {
16
17 namespace {
18
19 // The amount of time we'll wait to initialize sync if no data type triggers
20 // initialization via a StartSyncFlare.
21 const int kDeferredInitFallbackSeconds = 10;
22
23 // Enum (for UMA, primarily) defining different events that cause us to
24 // exit the "deferred" state of initialization and invoke start_backend.
25 enum DeferredInitTrigger {
26 // We have received a signal from a SyncableService requesting that sync
27 // starts as soon as possible.
28 TRIGGER_DATA_TYPE_REQUEST,
29 // No data type requested sync to start and our fallback timer expired.
30 TRIGGER_FALLBACK_TIMER,
31 MAX_TRIGGER_VALUE
32 };
33
34 } // namespace
35
36 StartupController::StartupController(
37 ProfileSyncServiceStartBehavior start_behavior,
38 ProfileOAuth2TokenService* token_service,
39 const browser_sync::SyncPrefs* sync_prefs,
40 const ManagedUserSigninManagerWrapper* signin,
41 base::Closure start_backend)
42 : received_start_request_(false),
43 setup_in_progress_(false),
44 auto_start_enabled_(start_behavior == AUTO_START),
45 sync_prefs_(sync_prefs),
46 token_service_(token_service),
47 signin_(signin),
48 start_backend_(start_backend),
49 fallback_timeout_(
50 base::TimeDelta::FromSeconds(kDeferredInitFallbackSeconds)),
51 weak_factory_(this) {}
52
53 StartupController::~StartupController() {}
54
55 void StartupController::Reset() {
56 received_start_request_ = false;
57 setup_in_progress_ = false;
58 start_up_time_ = base::Time();
59 start_backend_time_ = base::Time();
60 // Don't let previous timers affect us post-reset.
61 weak_factory_.InvalidateWeakPtrs();
62 }
63
64 void StartupController::set_setup_in_progress(bool in_progress) {
65 setup_in_progress_ = in_progress;
66 }
67
68 bool StartupController::StartUp(StartUpDeferredOption deferred_option) {
69 const bool first_start = start_up_time_.is_null();
70 if (first_start)
71 start_up_time_ = base::Time::Now();
72
73 if (deferred_option == STARTUP_BACKEND_DEFERRED &&
74 CommandLine::ForCurrentProcess()->
75 HasSwitch(switches::kSyncEnableDeferredStartup)) {
76 if (first_start) {
77 base::MessageLoop::current()->PostDelayedTask(
78 FROM_HERE,
79 base::Bind(&StartupController::OnFallbackStartupTimerExpired,
80 weak_factory_.GetWeakPtr()), fallback_timeout_);
81 }
82 return false;
83 }
84
85 if (start_backend_time_.is_null()) {
86 start_backend_time_ = base::Time::Now();
87 start_backend_.Run();
88 }
89
90 return true;
91 }
92
93 void StartupController::OverrideFallbackTimeoutForTest(
94 const base::TimeDelta& timeout) {
95 fallback_timeout_ = timeout;
96 }
97
98 bool StartupController::TryStart() {
99 if (sync_prefs_->IsManaged())
100 return false;
101
102 if (sync_prefs_->IsStartSuppressed())
103 return false;
104
105 if (signin_->GetEffectiveUsername().empty())
106 return false;
107
108 if (!token_service_)
109 return false;
110
111 if (!token_service_->RefreshTokenIsAvailable(
112 signin_->GetAccountIdToUse())) {
113 return false;
114 }
115
116 // TODO(tim): Seems wrong to always record this histogram here...
117 // If we got here then tokens are loaded and user logged in and sync is
118 // enabled. If OAuth refresh token is not available then something is wrong.
119 // When PSS requests access token, OAuth2TokenService will return error and
120 // PSS will show error to user asking to reauthenticate.
121 UMA_HISTOGRAM_BOOLEAN("Sync.RefreshTokenAvailable", true);
122
123 // If sync setup has completed we always start the backend. If the user is in
124 // the process of setting up now, we should start the backend to download
125 // account control state / encryption information). If autostart is enabled,
126 // but we haven't completed sync setup, we try to start sync anyway, since
127 // it's possible we crashed/shutdown after logging in but before the backend
128 // finished initializing the last time.
129 //
130 // However, the only time we actually need to start sync _immediately_ is if
131 // we haven't completed sync setup and the user is in the process of setting
132 // up - either they just signed in (for the first time) on an auto-start
133 // platform or they explicitly kicked off sync setup, and e.g we need to
134 // fetch account details like encryption state to populate UI. Otherwise,
135 // for performance reasons and maximizing parallelism at chrome startup, we
136 // defer the heavy lifting for sync init until things have calmed down.
137 if (sync_prefs_->HasSyncSetupCompleted()) {
138 if (!received_start_request_)
139 return StartUp(STARTUP_BACKEND_DEFERRED);
140 else
141 return StartUp(STARTUP_IMMEDIATE);
142 } else if (setup_in_progress_ || auto_start_enabled_) {
143 // We haven't completed sync setup. Start immediately if the user explicitly
144 // kicked this off or we're supposed to automatically start syncing.
145 return StartUp(STARTUP_IMMEDIATE);
146 }
147
148 return false;
haitaol1 2014/02/25 00:53:02 NOTREACHED()?
tim (not reviewing) 2014/02/25 01:17:44 We call TryStart pretty liberally in ProfileSyncSe
149 }
150
151 void StartupController::OnFallbackStartupTimerExpired() {
152 DCHECK(CommandLine::ForCurrentProcess()->HasSwitch(
153 switches::kSyncEnableDeferredStartup));
154
155 if (!start_backend_time_.is_null())
156 return;
157
158 DVLOG(2) << "Sync deferred init fallback timer expired, starting backend.";
159 DCHECK(!start_up_time_.is_null());
160 base::TimeDelta time_deferred = base::Time::Now() - start_up_time_;
161 UMA_HISTOGRAM_TIMES("Sync.Startup.TimeDeferred", time_deferred);
162 UMA_HISTOGRAM_ENUMERATION("Sync.Startup.DeferredInitTrigger",
163 TRIGGER_FALLBACK_TIMER,
164 MAX_TRIGGER_VALUE);
165 received_start_request_ = true;
166 TryStart();
167 }
168
169 std::string StartupController::GetBackendInitializationStateString() const {
170 if (!start_backend_time_.is_null())
171 return "Started";
172 else if (!start_up_time_.is_null())
173 return "Deferred";
174 else
175 return "Not started";
176 }
177
178 void StartupController::OnDataTypeRequestsSyncStartup(syncer::ModelType type) {
179 if (!CommandLine::ForCurrentProcess()->HasSwitch(
180 switches::kSyncEnableDeferredStartup)) {
181 DVLOG(2) << "Ignoring data type request for sync startup: "
182 << syncer::ModelTypeToString(type);
183 return;
184 }
185
186 if (!start_backend_time_.is_null())
187 return;
188
189 DVLOG(2) << "Data type requesting sync startup: "
190 << syncer::ModelTypeToString(type);
191 // Measure the time spent waiting for init and the type that triggered it.
192 // We could measure the time spent deferred on a per-datatype basis, but
193 // for now this is probably sufficient.
194 if (!start_up_time_.is_null()) {
195 base::TimeDelta time_deferred = base::Time::Now() - start_up_time_;
196 UMA_HISTOGRAM_TIMES("Sync.Startup.TimeDeferred", time_deferred);
197 UMA_HISTOGRAM_ENUMERATION("Sync.Startup.TypeTriggeringInit",
198 ModelTypeToHistogramInt(type),
199 syncer::MODEL_TYPE_COUNT);
200 UMA_HISTOGRAM_ENUMERATION("Sync.Startup.DeferredInitTrigger",
201 TRIGGER_DATA_TYPE_REQUEST,
202 MAX_TRIGGER_VALUE);
203 }
204 received_start_request_ = true;
205 TryStart();
206 }
207
208 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/startup_controller.h ('k') | chrome/browser/sync/startup_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698