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

Side by Side Diff: sync/engine/download.cc

Issue 17052007: sync: Expose sync functionality as functions (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review fixes (not tested nor rebased) Created 7 years, 6 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 2012 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 "sync/engine/download.h"
6
7 #include <string>
8
9 #include "base/command_line.h"
10 #include "sync/engine/process_updates_command.h"
11 #include "sync/engine/store_timestamps_command.h"
12 #include "sync/engine/syncer.h"
13 #include "sync/engine/syncer_proto_util.h"
14 #include "sync/internal_api/public/base/model_type_invalidation_map.h"
15 #include "sync/sessions/nudge_tracker.h"
16 #include "sync/syncable/directory.h"
17 #include "sync/syncable/nigori_handler.h"
18 #include "sync/syncable/syncable_read_transaction.h"
19
20 using sync_pb::DebugInfo;
21
22 namespace syncer {
23
24 using sessions::StatusController;
25 using sessions::SyncSession;
26 using sessions::SyncSessionContext;
27 using std::string;
28
29 namespace {
30
31 SyncerError HandleGetEncryptionKeyResponse(
32 const sync_pb::ClientToServerResponse& update_response,
33 syncable::Directory* dir) {
34 bool success = false;
35 if (update_response.get_updates().encryption_keys_size() == 0) {
36 LOG(ERROR) << "Failed to receive encryption key from server.";
37 return SERVER_RESPONSE_VALIDATION_FAILED;
38 }
39 syncable::ReadTransaction trans(FROM_HERE, dir);
40 syncable::NigoriHandler* nigori_handler = dir->GetNigoriHandler();
41 success = nigori_handler->SetKeystoreKeys(
42 update_response.get_updates().encryption_keys(),
43 &trans);
44
45 DVLOG(1) << "GetUpdates returned "
46 << update_response.get_updates().encryption_keys_size()
47 << "encryption keys. Nigori keystore key "
48 << (success ? "" : "not ") << "updated.";
49 return (success ? SYNCER_OK : SERVER_RESPONSE_VALIDATION_FAILED);
50 }
51
52 sync_pb::SyncEnums::GetUpdatesOrigin ConvertConfigureSourceToOrigin(
53 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source) {
54 switch (source) {
55 // Configurations:
56 case sync_pb::GetUpdatesCallerInfo::NEWLY_SUPPORTED_DATATYPE:
57 return sync_pb::SyncEnums::NEWLY_SUPPORTED_DATATYPE;
58 case sync_pb::GetUpdatesCallerInfo::MIGRATION:
59 return sync_pb::SyncEnums::MIGRATION;
60 case sync_pb::GetUpdatesCallerInfo::RECONFIGURATION:
61 return sync_pb::SyncEnums::RECONFIGURATION;
62 case sync_pb::GetUpdatesCallerInfo::NEW_CLIENT:
63 return sync_pb::SyncEnums::NEW_CLIENT;
64 default:
65 NOTREACHED();
66 return sync_pb::SyncEnums::UNKNOWN_ORIGIN;
67 }
68 }
69
70 sync_pb::GetUpdatesMessage* InitDownloadUpdatesRequest(
71 sync_pb::ClientToServerMessage* msg) {
72 msg->set_message_contents(sync_pb::ClientToServerMessage::GET_UPDATES);
73
74 // We want folders for our associated types, always. If we were to set
75 // this to false, the server would send just the non-container items
76 // (e.g. Bookmark URLs but not their containing folders).
77 sync_pb::GetUpdatesMessage* get_updates = msg->mutable_get_updates();
78 get_updates->set_fetch_folders(true);
79 return get_updates;
80 }
81
82 bool ShouldRequestEncryptionKey(
83 SyncSessionContext* context) {
84 bool need_encryption_key = false;
85 if (context->keystore_encryption_enabled()) {
86 syncable::Directory* dir = context->directory();
87 syncable::ReadTransaction trans(FROM_HERE, dir);
88 syncable::NigoriHandler* nigori_handler = dir->GetNigoriHandler();
89 need_encryption_key = nigori_handler->NeedKeystoreKey(&trans);
90 }
91 return need_encryption_key;
92 }
93
94 SyncerError ExecuteDownloadUpdates(
95 bool need_encryption_key,
96 SyncSession* session,
97 sync_pb::ClientToServerMessage* msg) {
98 sync_pb::ClientToServerResponse update_response;
99 StatusController* status = session->mutable_status_controller();
100
101 SyncerError result = SyncerProtoUtil::PostClientToServerMessage(
102 msg,
103 &update_response,
104 session);
105
106 DVLOG(2) << SyncerProtoUtil::ClientToServerResponseDebugString(
107 update_response);
108
109 if (result != SYNCER_OK) {
110 status->mutable_updates_response()->Clear();
111 LOG(ERROR) << "PostClientToServerMessage() failed during GetUpdates";
112 return result;
113 }
114
115 status->mutable_updates_response()->CopyFrom(update_response);
116
117 DVLOG(1) << "GetUpdates "
118 << " returned " << update_response.get_updates().entries_size()
119 << " updates and indicated "
120 << update_response.get_updates().changes_remaining()
121 << " updates left on server.";
122
123 if (need_encryption_key ||
124 update_response.get_updates().encryption_keys_size() > 0) {
125 syncable::Directory* dir = session->context()->directory();
126 status->set_last_get_key_result(
127 HandleGetEncryptionKeyResponse(update_response, dir));
128 }
129
130 ProcessUpdatesCommand process_updates;
131 process_updates.Execute(session);
132
133 StoreTimestampsCommand store_timestamps;
134 store_timestamps.Execute(session);
135
136 return result;
137 }
138
139 } // namespace
140
141 SyncerError NormalDownloadUpdates(
142 SyncSession* session,
143 bool create_mobile_bookmarks_folder,
144 ModelTypeSet request_types,
145 const sessions::NudgeTracker& nudge_tracker) {
146 sync_pb::ClientToServerMessage client_to_server_message;
147 client_to_server_message.set_share(session->context()->account_name());
148 sync_pb::GetUpdatesMessage* get_updates =
149 InitDownloadUpdatesRequest(&client_to_server_message);
150
151 DebugInfo* debug_info = client_to_server_message.mutable_debug_info();
152 AppendClientDebugInfoIfNeeded(session, debug_info);
153
154 get_updates->set_create_mobile_bookmarks_folder(
155 create_mobile_bookmarks_folder);
156 bool need_encryption_key = ShouldRequestEncryptionKey(session->context());
157 get_updates->set_need_encryption_key(need_encryption_key);
158
159 // Request updates for all requested types.
160 DVLOG(1) << "Getting updates for types "
161 << ModelTypeSetToString(request_types);
162 DCHECK(!request_types.Empty());
163
164 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information.
165 get_updates->mutable_caller_info()->set_source(
166 nudge_tracker.updates_source());
167 get_updates->mutable_caller_info()->set_notifications_enabled(
168 session->context()->notifications_enabled());
169
170 // Set the new and improved version of source, too.
171 get_updates->set_get_updates_origin(sync_pb::SyncEnums::GU_TRIGGER);
172
173 // Set the progress markers and notification hints.
174 syncable::Directory* dir = session->context()->directory();
175 for (ModelTypeSet::Iterator it = request_types.First();
176 it.Good(); it.Inc()) {
177 if (ProxyTypes().Has(it.Get()))
178 continue;
179
180 DCHECK(!nudge_tracker.IsTypeThrottled(it.Get()))
181 << "Throttled types should have been removed from the request_types.";
182
183 sync_pb::DataTypeProgressMarker* progress_marker =
184 get_updates->add_from_progress_marker();
185 dir->GetDownloadProgress(it.Get(), progress_marker);
186 nudge_tracker.SetLegacyNotificationHint(it.Get(), progress_marker);
187 nudge_tracker.FillProtoMessage(
188 it.Get(),
189 progress_marker->mutable_get_update_triggers());
190 }
191
192 StatusController* status = session->mutable_status_controller();
193 status->set_updates_request_types(request_types);
194 return ExecuteDownloadUpdates(
195 need_encryption_key,
196 session,
197 &client_to_server_message);
198 }
199
200 SyncerError ConfigureDownloadUpdates(
201 SyncSession* session,
202 bool create_mobile_bookmarks_folder,
203 const syncer::sessions::SyncSourceInfo& source,
204 ModelTypeSet request_types) {
205 sync_pb::ClientToServerMessage client_to_server_message;
206 client_to_server_message.set_share(session->context()->account_name());
207 sync_pb::GetUpdatesMessage* get_updates =
208 InitDownloadUpdatesRequest(&client_to_server_message);
209
210 DebugInfo* debug_info = client_to_server_message.mutable_debug_info();
211 AppendClientDebugInfoIfNeeded(session, debug_info);
212
213 get_updates->set_create_mobile_bookmarks_folder(
214 create_mobile_bookmarks_folder);
215 bool need_encryption_key = ShouldRequestEncryptionKey(session->context());
216 get_updates->set_need_encryption_key(need_encryption_key);
217
218 // Request updates for all enabled types.
219 DVLOG(1) << "Initial download for types "
220 << ModelTypeSetToString(request_types);
221 DCHECK(!request_types.Empty());
222
223 syncable::Directory* dir = session->context()->directory();
224 for (ModelTypeSet::Iterator it = request_types.First();
225 it.Good(); it.Inc()) {
226 if (ProxyTypes().Has(it.Get()))
227 continue;
228
229 sync_pb::DataTypeProgressMarker* progress_marker =
230 get_updates->add_from_progress_marker();
231 dir->GetDownloadProgress(it.Get(), progress_marker);
232 }
233
234 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information.
235 get_updates->mutable_caller_info()->set_source(source.updates_source);
236 get_updates->mutable_caller_info()->set_notifications_enabled(
237 session->context()->notifications_enabled());
238
239 // Set the new and improved version of source, too.
240 sync_pb::SyncEnums::GetUpdatesOrigin origin =
241 ConvertConfigureSourceToOrigin(source.updates_source);
242 get_updates->set_get_updates_origin(origin);
243
244 StatusController* status = session->mutable_status_controller();
245 status->set_updates_request_types(request_types);
246 return ExecuteDownloadUpdates(
247 need_encryption_key,
248 session,
249 &client_to_server_message);
250 }
251
252 SyncerError PollDownloadUpdates(
253 SyncSession* session,
254 bool create_mobile_bookmarks_folder,
255 ModelTypeSet request_types) {
256 sync_pb::ClientToServerMessage client_to_server_message;
257 client_to_server_message.set_share(session->context()->account_name());
258 sync_pb::GetUpdatesMessage* get_updates =
259 InitDownloadUpdatesRequest(&client_to_server_message);
260
261 DebugInfo* debug_info = client_to_server_message.mutable_debug_info();
262 AppendClientDebugInfoIfNeeded(session, debug_info);
263
264 get_updates->set_create_mobile_bookmarks_folder(
265 create_mobile_bookmarks_folder);
266 bool need_encryption_key = ShouldRequestEncryptionKey(session->context());
267 get_updates->set_need_encryption_key(need_encryption_key);
268
269 DVLOG(1) << "Polling for types "
270 << ModelTypeSetToString(request_types);
271 DCHECK(!request_types.Empty());
272
273 syncable::Directory* dir = session->context()->directory();
274 for (ModelTypeSet::Iterator it = request_types.First();
275 it.Good(); it.Inc()) {
276 if (ProxyTypes().Has(it.Get()))
277 continue;
278
279 sync_pb::DataTypeProgressMarker* progress_marker =
280 get_updates->add_from_progress_marker();
281 dir->GetDownloadProgress(it.Get(), progress_marker);
282 }
283
284 DCHECK_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC,
285 session->source().updates_source);
286
287 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information.
288 get_updates->mutable_caller_info()->set_source(
289 sync_pb::GetUpdatesCallerInfo::PERIODIC);
290 get_updates->mutable_caller_info()->set_notifications_enabled(
291 session->context()->notifications_enabled());
292
293 // Set the new and improved version of source, too.
294 get_updates->set_get_updates_origin(sync_pb::SyncEnums::PERIODIC);
295
296 StatusController* status = session->mutable_status_controller();
297 status->set_updates_request_types(request_types);
298 return ExecuteDownloadUpdates(
299 need_encryption_key,
300 session,
301 &client_to_server_message);
302 }
303
304 void AppendClientDebugInfoIfNeeded(
305 SyncSession* session,
306 DebugInfo* debug_info) {
307 // We want to send the debug info only once per sync cycle. Check if it has
308 // already been sent.
309 if (!session->status_controller().debug_info_sent()) {
310 DVLOG(1) << "Sending client debug info ...";
311 // could be null in some unit tests.
312 if (session->context()->debug_info_getter()) {
313 session->context()->debug_info_getter()->GetAndClearDebugInfo(
314 debug_info);
315 }
316 session->mutable_status_controller()->set_debug_info_sent();
317 }
318 }
319
320 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698