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

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: Refactor SyncShare function signatures 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 } else {
113 status->mutable_updates_response()->CopyFrom(update_response);
114
115 DVLOG(1) << "GetUpdates "
116 << " returned " << update_response.get_updates().entries_size()
117 << " updates and indicated "
118 << update_response.get_updates().changes_remaining()
119 << " updates left on server.";
120
121 if (need_encryption_key ||
122 update_response.get_updates().encryption_keys_size() > 0) {
123 syncable::Directory* dir = session->context()->directory();
124 status->set_last_get_key_result(
125 HandleGetEncryptionKeyResponse(update_response, dir));
126 }
127 }
128
129 ProcessUpdatesCommand process_updates;
130 process_updates.Execute(session);
131
132 StoreTimestampsCommand store_timestamps;
133 store_timestamps.Execute(session);
134
135 return result;
136 }
137
138 } // namespace
139
140 SyncerError NormalDownloadUpdates(
141 SyncSession* session,
142 bool create_mobile_bookmarks_folder,
143 ModelTypeSet request_types,
144 const sessions::NudgeTracker& nudge_tracker) {
145 sync_pb::ClientToServerMessage client_to_server_message;
146 client_to_server_message.set_share(session->context()->account_name());
147 sync_pb::GetUpdatesMessage* get_updates =
148 InitDownloadUpdatesRequest(&client_to_server_message);
149
150 DebugInfo* debug_info = client_to_server_message.mutable_debug_info();
151 AppendClientDebugInfoIfNeeded(session, debug_info);
152
153 get_updates->set_create_mobile_bookmarks_folder(
154 create_mobile_bookmarks_folder);
155 bool need_encryption_key = ShouldRequestEncryptionKey(session->context());
156 get_updates->set_need_encryption_key(need_encryption_key);
157
158 // Request updates for all requested types.
159 DVLOG(1) << "Getting updates for types "
160 << ModelTypeSetToString(request_types);
161 DCHECK(!request_types.Empty());
tim (not reviewing) 2013/06/26 20:26:30 There's just too much duplicated code here. I thin
rlarocque 2013/06/26 22:00:51 I've expanded InitDownloadUpdates to include more
162
163 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information.
164 get_updates->mutable_caller_info()->set_source(
165 nudge_tracker.updates_source());
tim (not reviewing) 2013/06/26 20:26:30 The GetUpdatesCallerInfo setting seems to be the s
rlarocque 2013/06/26 22:00:51 That will change. The SyncSourceInfo becomes redu
166 get_updates->mutable_caller_info()->set_notifications_enabled(
167 session->context()->notifications_enabled());
168
169 // Set the new and improved version of source, too.
170 get_updates->set_get_updates_origin(sync_pb::SyncEnums::GU_TRIGGER);
171
172 // Set the progress markers and notification hints.
173 syncable::Directory* dir = session->context()->directory();
174 for (ModelTypeSet::Iterator it = request_types.First();
175 it.Good(); it.Inc()) {
176 if (ProxyTypes().Has(it.Get()))
177 continue;
178
179 DCHECK(!nudge_tracker.IsTypeThrottled(it.Get()))
180 << "Throttled types should have been removed from the request_types.";
181
182 sync_pb::DataTypeProgressMarker* progress_marker =
183 get_updates->add_from_progress_marker();
184 dir->GetDownloadProgress(it.Get(), progress_marker);
185 nudge_tracker.SetLegacyNotificationHint(it.Get(), progress_marker);
186 nudge_tracker.FillProtoMessage(
187 it.Get(),
188 progress_marker->mutable_get_update_triggers());
189 }
190
191 StatusController* status = session->mutable_status_controller();
192 status->set_updates_request_types(request_types);
193 return ExecuteDownloadUpdates(
194 need_encryption_key,
195 session,
196 &client_to_server_message);
197 }
198
199 SyncerError ConfigureDownloadUpdates(
200 SyncSession* session,
201 bool create_mobile_bookmarks_folder,
202 const syncer::sessions::SyncSourceInfo& source,
203 ModelTypeSet request_types) {
204 sync_pb::ClientToServerMessage client_to_server_message;
205 client_to_server_message.set_share(session->context()->account_name());
206 sync_pb::GetUpdatesMessage* get_updates =
207 InitDownloadUpdatesRequest(&client_to_server_message);
208
209 DebugInfo* debug_info = client_to_server_message.mutable_debug_info();
210 AppendClientDebugInfoIfNeeded(session, debug_info);
211
212 get_updates->set_create_mobile_bookmarks_folder(
213 create_mobile_bookmarks_folder);
214 bool need_encryption_key = ShouldRequestEncryptionKey(session->context());
215 get_updates->set_need_encryption_key(need_encryption_key);
216
217 // Request updates for all enabled types.
218 DVLOG(1) << "Initial download for types "
219 << ModelTypeSetToString(request_types);
220 DCHECK(!request_types.Empty());
221
222 syncable::Directory* dir = session->context()->directory();
223 for (ModelTypeSet::Iterator it = request_types.First();
224 it.Good(); it.Inc()) {
225 if (ProxyTypes().Has(it.Get()))
226 continue;
227
228 sync_pb::DataTypeProgressMarker* progress_marker =
229 get_updates->add_from_progress_marker();
230 dir->GetDownloadProgress(it.Get(), progress_marker);
231 }
232
233 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information.
234 get_updates->mutable_caller_info()->set_source(source.updates_source);
235 get_updates->mutable_caller_info()->set_notifications_enabled(
236 session->context()->notifications_enabled());
237
238 // Set the new and improved version of source, too.
239 sync_pb::SyncEnums::GetUpdatesOrigin origin =
240 ConvertConfigureSourceToOrigin(source.updates_source);
241 get_updates->set_get_updates_origin(origin);
242
243 StatusController* status = session->mutable_status_controller();
244 status->set_updates_request_types(request_types);
245 return ExecuteDownloadUpdates(
246 need_encryption_key,
247 session,
248 &client_to_server_message);
249 }
250
251 SyncerError PollDownloadUpdates(
252 SyncSession* session,
253 bool create_mobile_bookmarks_folder,
254 ModelTypeSet request_types) {
255 sync_pb::ClientToServerMessage client_to_server_message;
256 client_to_server_message.set_share(session->context()->account_name());
257 sync_pb::GetUpdatesMessage* get_updates =
258 InitDownloadUpdatesRequest(&client_to_server_message);
259
260 DebugInfo* debug_info = client_to_server_message.mutable_debug_info();
261 AppendClientDebugInfoIfNeeded(session, debug_info);
262
263 get_updates->set_create_mobile_bookmarks_folder(
264 create_mobile_bookmarks_folder);
265 bool need_encryption_key = ShouldRequestEncryptionKey(session->context());
266 get_updates->set_need_encryption_key(need_encryption_key);
267
268 DVLOG(1) << "Polling for types "
269 << ModelTypeSetToString(request_types);
270 DCHECK(!request_types.Empty());
271
272 syncable::Directory* dir = session->context()->directory();
273 for (ModelTypeSet::Iterator it = request_types.First();
274 it.Good(); it.Inc()) {
275 if (ProxyTypes().Has(it.Get()))
276 continue;
277
278 sync_pb::DataTypeProgressMarker* progress_marker =
279 get_updates->add_from_progress_marker();
280 dir->GetDownloadProgress(it.Get(), progress_marker);
281 }
282
283 DCHECK_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC,
284 session->source().updates_source);
285
286 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information.
287 get_updates->mutable_caller_info()->set_source(
288 sync_pb::GetUpdatesCallerInfo::PERIODIC);
289 get_updates->mutable_caller_info()->set_notifications_enabled(
290 session->context()->notifications_enabled());
291
292 // Set the new and improved version of source, too.
293 get_updates->set_get_updates_origin(sync_pb::SyncEnums::PERIODIC);
294
295 StatusController* status = session->mutable_status_controller();
296 status->set_updates_request_types(request_types);
297 return ExecuteDownloadUpdates(
298 need_encryption_key,
299 session,
300 &client_to_server_message);
301 }
302
303 void AppendClientDebugInfoIfNeeded(
304 SyncSession* session,
305 DebugInfo* debug_info) {
306 // We want to send the debug info only once per sync cycle. Check if it has
307 // already been sent.
308 if (!session->status_controller().debug_info_sent()) {
309 DVLOG(1) << "Sending client debug info ...";
310 // could be null in some unit tests.
311 if (session->context()->debug_info_getter()) {
312 session->context()->debug_info_getter()->GetAndClearDebugInfo(
313 debug_info);
314 }
315 session->mutable_status_controller()->set_debug_info_sent();
316 }
317 }
318
319 } // namespace syncer
OLDNEW
« no previous file with comments | « sync/engine/download.h ('k') | sync/engine/download_unittest.cc » ('j') | sync/engine/syncer.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698