OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/sync_file_system/local/local_file_sync_service.h" | 5 #include "chrome/browser/sync_file_system/local/local_file_sync_service.h" |
6 | 6 |
7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
8 #include "base/single_thread_task_runner.h" | 8 #include "base/single_thread_task_runner.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 bool LocalFileSyncService::OriginChangeMap::NextOriginToProcess(GURL* origin) { | 58 bool LocalFileSyncService::OriginChangeMap::NextOriginToProcess(GURL* origin) { |
59 DCHECK(origin); | 59 DCHECK(origin); |
60 if (change_count_map_.empty()) | 60 if (change_count_map_.empty()) |
61 return false; | 61 return false; |
62 Map::iterator begin = next_; | 62 Map::iterator begin = next_; |
63 do { | 63 do { |
64 if (next_ == change_count_map_.end()) | 64 if (next_ == change_count_map_.end()) |
65 next_ = change_count_map_.begin(); | 65 next_ = change_count_map_.begin(); |
66 DCHECK_NE(0, next_->second); | 66 DCHECK_NE(0, next_->second); |
67 *origin = next_++->first; | 67 *origin = next_++->first; |
68 if (!ContainsKey(disabled_origins_, *origin)) | 68 if (!base::ContainsKey(disabled_origins_, *origin)) |
69 return true; | 69 return true; |
70 } while (next_ != begin); | 70 } while (next_ != begin); |
71 return false; | 71 return false; |
72 } | 72 } |
73 | 73 |
74 int64_t LocalFileSyncService::OriginChangeMap::GetTotalChangeCount() const { | 74 int64_t LocalFileSyncService::OriginChangeMap::GetTotalChangeCount() const { |
75 int64_t num_changes = 0; | 75 int64_t num_changes = 0; |
76 for (Map::const_iterator iter = change_count_map_.begin(); | 76 for (Map::const_iterator iter = change_count_map_.begin(); |
77 iter != change_count_map_.end(); ++iter) { | 77 iter != change_count_map_.end(); ++iter) { |
78 if (ContainsKey(disabled_origins_, iter->first)) | 78 if (base::ContainsKey(disabled_origins_, iter->first)) |
79 continue; | 79 continue; |
80 num_changes += iter->second; | 80 num_changes += iter->second; |
81 } | 81 } |
82 return num_changes; | 82 return num_changes; |
83 } | 83 } |
84 | 84 |
85 void LocalFileSyncService::OriginChangeMap::SetOriginChangeCount( | 85 void LocalFileSyncService::OriginChangeMap::SetOriginChangeCount( |
86 const GURL& origin, | 86 const GURL& origin, |
87 int64_t changes) { | 87 int64_t changes) { |
88 if (changes != 0) { | 88 if (changes != 0) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 | 154 |
155 void LocalFileSyncService::ProcessLocalChange( | 155 void LocalFileSyncService::ProcessLocalChange( |
156 const SyncFileCallback& callback) { | 156 const SyncFileCallback& callback) { |
157 // Pick an origin to process next. | 157 // Pick an origin to process next. |
158 GURL origin; | 158 GURL origin; |
159 if (!origin_change_map_.NextOriginToProcess(&origin)) { | 159 if (!origin_change_map_.NextOriginToProcess(&origin)) { |
160 callback.Run(SYNC_STATUS_NO_CHANGE_TO_SYNC, FileSystemURL()); | 160 callback.Run(SYNC_STATUS_NO_CHANGE_TO_SYNC, FileSystemURL()); |
161 return; | 161 return; |
162 } | 162 } |
163 DCHECK(!origin.is_empty()); | 163 DCHECK(!origin.is_empty()); |
164 DCHECK(ContainsKey(origin_to_contexts_, origin)); | 164 DCHECK(base::ContainsKey(origin_to_contexts_, origin)); |
165 | 165 |
166 DVLOG(1) << "Starting ProcessLocalChange"; | 166 DVLOG(1) << "Starting ProcessLocalChange"; |
167 | 167 |
168 sync_context_->GetFileForLocalSync( | 168 sync_context_->GetFileForLocalSync( |
169 origin_to_contexts_[origin], | 169 origin_to_contexts_[origin], |
170 base::Bind(&LocalFileSyncService::DidGetFileForLocalSync, | 170 base::Bind(&LocalFileSyncService::DidGetFileForLocalSync, |
171 AsWeakPtr(), callback)); | 171 AsWeakPtr(), callback)); |
172 } | 172 } |
173 | 173 |
174 void LocalFileSyncService::SetLocalChangeProcessor( | 174 void LocalFileSyncService::SetLocalChangeProcessor( |
175 LocalChangeProcessor* local_change_processor) { | 175 LocalChangeProcessor* local_change_processor) { |
176 local_change_processor_ = local_change_processor; | 176 local_change_processor_ = local_change_processor; |
177 } | 177 } |
178 | 178 |
179 void LocalFileSyncService::SetLocalChangeProcessorCallback( | 179 void LocalFileSyncService::SetLocalChangeProcessorCallback( |
180 const GetLocalChangeProcessorCallback& get_local_change_processor) { | 180 const GetLocalChangeProcessorCallback& get_local_change_processor) { |
181 get_local_change_processor_ = get_local_change_processor; | 181 get_local_change_processor_ = get_local_change_processor; |
182 } | 182 } |
183 | 183 |
184 void LocalFileSyncService::HasPendingLocalChanges( | 184 void LocalFileSyncService::HasPendingLocalChanges( |
185 const FileSystemURL& url, | 185 const FileSystemURL& url, |
186 const HasPendingLocalChangeCallback& callback) { | 186 const HasPendingLocalChangeCallback& callback) { |
187 if (!ContainsKey(origin_to_contexts_, url.origin())) { | 187 if (!base::ContainsKey(origin_to_contexts_, url.origin())) { |
188 base::ThreadTaskRunnerHandle::Get()->PostTask( | 188 base::ThreadTaskRunnerHandle::Get()->PostTask( |
189 FROM_HERE, | 189 FROM_HERE, |
190 base::Bind(callback, SYNC_FILE_ERROR_INVALID_URL, false)); | 190 base::Bind(callback, SYNC_FILE_ERROR_INVALID_URL, false)); |
191 return; | 191 return; |
192 } | 192 } |
193 sync_context_->HasPendingLocalChanges( | 193 sync_context_->HasPendingLocalChanges( |
194 origin_to_contexts_[url.origin()], url, callback); | 194 origin_to_contexts_[url.origin()], url, callback); |
195 } | 195 } |
196 | 196 |
197 void LocalFileSyncService::PromoteDemotedChanges( | 197 void LocalFileSyncService::PromoteDemotedChanges( |
198 const base::Closure& callback) { | 198 const base::Closure& callback) { |
199 if (origin_to_contexts_.empty()) { | 199 if (origin_to_contexts_.empty()) { |
200 callback.Run(); | 200 callback.Run(); |
201 return; | 201 return; |
202 } | 202 } |
203 | 203 |
204 base::Closure completion_callback = | 204 base::Closure completion_callback = |
205 base::Bind(&InvokeCallbackOnNthInvocation, | 205 base::Bind(&InvokeCallbackOnNthInvocation, |
206 base::Owned(new int(origin_to_contexts_.size() + 1)), | 206 base::Owned(new int(origin_to_contexts_.size() + 1)), |
207 callback); | 207 callback); |
208 for (OriginToContext::iterator iter = origin_to_contexts_.begin(); | 208 for (OriginToContext::iterator iter = origin_to_contexts_.begin(); |
209 iter != origin_to_contexts_.end(); ++iter) | 209 iter != origin_to_contexts_.end(); ++iter) |
210 sync_context_->PromoteDemotedChanges(iter->first, iter->second, | 210 sync_context_->PromoteDemotedChanges(iter->first, iter->second, |
211 completion_callback); | 211 completion_callback); |
212 completion_callback.Run(); | 212 completion_callback.Run(); |
213 } | 213 } |
214 | 214 |
215 void LocalFileSyncService::GetLocalFileMetadata( | 215 void LocalFileSyncService::GetLocalFileMetadata( |
216 const FileSystemURL& url, const SyncFileMetadataCallback& callback) { | 216 const FileSystemURL& url, const SyncFileMetadataCallback& callback) { |
217 DCHECK(ContainsKey(origin_to_contexts_, url.origin())); | 217 DCHECK(base::ContainsKey(origin_to_contexts_, url.origin())); |
218 sync_context_->GetFileMetadata(origin_to_contexts_[url.origin()], | 218 sync_context_->GetFileMetadata(origin_to_contexts_[url.origin()], |
219 url, callback); | 219 url, callback); |
220 } | 220 } |
221 | 221 |
222 void LocalFileSyncService::PrepareForProcessRemoteChange( | 222 void LocalFileSyncService::PrepareForProcessRemoteChange( |
223 const FileSystemURL& url, | 223 const FileSystemURL& url, |
224 const PrepareChangeCallback& callback) { | 224 const PrepareChangeCallback& callback) { |
225 DVLOG(1) << "PrepareForProcessRemoteChange: " << url.DebugString(); | 225 DVLOG(1) << "PrepareForProcessRemoteChange: " << url.DebugString(); |
226 | 226 |
227 if (!ContainsKey(origin_to_contexts_, url.origin())) { | 227 if (!base::ContainsKey(origin_to_contexts_, url.origin())) { |
228 // This could happen if a remote sync is triggered for the app that hasn't | 228 // This could happen if a remote sync is triggered for the app that hasn't |
229 // been initialized in this service. | 229 // been initialized in this service. |
230 DCHECK(profile_); | 230 DCHECK(profile_); |
231 // The given url.origin() must be for valid installed app. | 231 // The given url.origin() must be for valid installed app. |
232 const extensions::Extension* extension = | 232 const extensions::Extension* extension = |
233 extensions::ExtensionRegistry::Get(profile_) | 233 extensions::ExtensionRegistry::Get(profile_) |
234 ->enabled_extensions().GetAppByURL(url.origin()); | 234 ->enabled_extensions().GetAppByURL(url.origin()); |
235 if (!extension) { | 235 if (!extension) { |
236 util::Log( | 236 util::Log( |
237 logging::LOG_WARNING, | 237 logging::LOG_WARNING, |
(...skipping 14 matching lines...) Expand all Loading... |
252 content::BrowserContext::GetStoragePartitionForSite(profile_, site_url) | 252 content::BrowserContext::GetStoragePartitionForSite(profile_, site_url) |
253 ->GetFileSystemContext(); | 253 ->GetFileSystemContext(); |
254 MaybeInitializeFileSystemContext( | 254 MaybeInitializeFileSystemContext( |
255 url.origin(), file_system_context.get(), | 255 url.origin(), file_system_context.get(), |
256 base::Bind(&LocalFileSyncService::DidInitializeForRemoteSync, | 256 base::Bind(&LocalFileSyncService::DidInitializeForRemoteSync, |
257 AsWeakPtr(), url, base::RetainedRef(file_system_context), | 257 AsWeakPtr(), url, base::RetainedRef(file_system_context), |
258 callback)); | 258 callback)); |
259 return; | 259 return; |
260 } | 260 } |
261 | 261 |
262 DCHECK(ContainsKey(origin_to_contexts_, url.origin())); | 262 DCHECK(base::ContainsKey(origin_to_contexts_, url.origin())); |
263 sync_context_->PrepareForSync( | 263 sync_context_->PrepareForSync( |
264 origin_to_contexts_[url.origin()], url, | 264 origin_to_contexts_[url.origin()], url, |
265 LocalFileSyncContext::SYNC_EXCLUSIVE, | 265 LocalFileSyncContext::SYNC_EXCLUSIVE, |
266 base::Bind(&PrepareForProcessRemoteChangeCallbackAdapter, callback)); | 266 base::Bind(&PrepareForProcessRemoteChangeCallbackAdapter, callback)); |
267 } | 267 } |
268 | 268 |
269 void LocalFileSyncService::ApplyRemoteChange( | 269 void LocalFileSyncService::ApplyRemoteChange( |
270 const FileChange& change, | 270 const FileChange& change, |
271 const base::FilePath& local_path, | 271 const base::FilePath& local_path, |
272 const FileSystemURL& url, | 272 const FileSystemURL& url, |
273 const SyncStatusCallback& callback) { | 273 const SyncStatusCallback& callback) { |
274 DCHECK(ContainsKey(origin_to_contexts_, url.origin())); | 274 DCHECK(base::ContainsKey(origin_to_contexts_, url.origin())); |
275 util::Log(logging::LOG_VERBOSE, FROM_HERE, | 275 util::Log(logging::LOG_VERBOSE, FROM_HERE, |
276 "[Remote -> Local] ApplyRemoteChange: %s on %s", | 276 "[Remote -> Local] ApplyRemoteChange: %s on %s", |
277 change.DebugString().c_str(), | 277 change.DebugString().c_str(), |
278 url.DebugString().c_str()); | 278 url.DebugString().c_str()); |
279 | 279 |
280 sync_context_->ApplyRemoteChange( | 280 sync_context_->ApplyRemoteChange( |
281 origin_to_contexts_[url.origin()], | 281 origin_to_contexts_[url.origin()], |
282 change, local_path, url, | 282 change, local_path, url, |
283 base::Bind(&LocalFileSyncService::DidApplyRemoteChange, AsWeakPtr(), | 283 base::Bind(&LocalFileSyncService::DidApplyRemoteChange, AsWeakPtr(), |
284 callback)); | 284 callback)); |
285 } | 285 } |
286 | 286 |
287 void LocalFileSyncService::FinalizeRemoteSync( | 287 void LocalFileSyncService::FinalizeRemoteSync( |
288 const FileSystemURL& url, | 288 const FileSystemURL& url, |
289 bool clear_local_changes, | 289 bool clear_local_changes, |
290 const base::Closure& completion_callback) { | 290 const base::Closure& completion_callback) { |
291 DCHECK(ContainsKey(origin_to_contexts_, url.origin())); | 291 DCHECK(base::ContainsKey(origin_to_contexts_, url.origin())); |
292 sync_context_->FinalizeExclusiveSync( | 292 sync_context_->FinalizeExclusiveSync( |
293 origin_to_contexts_[url.origin()], | 293 origin_to_contexts_[url.origin()], |
294 url, clear_local_changes, completion_callback); | 294 url, clear_local_changes, completion_callback); |
295 } | 295 } |
296 | 296 |
297 void LocalFileSyncService::RecordFakeLocalChange( | 297 void LocalFileSyncService::RecordFakeLocalChange( |
298 const FileSystemURL& url, | 298 const FileSystemURL& url, |
299 const FileChange& change, | 299 const FileChange& change, |
300 const SyncStatusCallback& callback) { | 300 const SyncStatusCallback& callback) { |
301 DCHECK(ContainsKey(origin_to_contexts_, url.origin())); | 301 DCHECK(base::ContainsKey(origin_to_contexts_, url.origin())); |
302 sync_context_->RecordFakeLocalChange(origin_to_contexts_[url.origin()], | 302 sync_context_->RecordFakeLocalChange(origin_to_contexts_[url.origin()], |
303 url, change, callback); | 303 url, change, callback); |
304 } | 304 } |
305 | 305 |
306 void LocalFileSyncService::OnChangesAvailableInOrigins( | 306 void LocalFileSyncService::OnChangesAvailableInOrigins( |
307 const std::set<GURL>& origins) { | 307 const std::set<GURL>& origins) { |
308 bool need_notification = false; | 308 bool need_notification = false; |
309 for (std::set<GURL>::const_iterator iter = origins.begin(); | 309 for (std::set<GURL>::const_iterator iter = origins.begin(); |
310 iter != origins.end(); ++iter) { | 310 iter != origins.end(); ++iter) { |
311 const GURL& origin = *iter; | 311 const GURL& origin = *iter; |
312 if (!ContainsKey(origin_to_contexts_, origin)) { | 312 if (!base::ContainsKey(origin_to_contexts_, origin)) { |
313 // This could happen if this is called for apps/origins that haven't | 313 // This could happen if this is called for apps/origins that haven't |
314 // been initialized yet, or for apps/origins that are disabled. | 314 // been initialized yet, or for apps/origins that are disabled. |
315 // (Local change tracker could call this for uninitialized origins | 315 // (Local change tracker could call this for uninitialized origins |
316 // while it's reading dirty files from the database in the | 316 // while it's reading dirty files from the database in the |
317 // initialization phase.) | 317 // initialization phase.) |
318 pending_origins_with_changes_.insert(origin); | 318 pending_origins_with_changes_.insert(origin); |
319 continue; | 319 continue; |
320 } | 320 } |
321 need_notification = true; | 321 need_notification = true; |
322 SyncFileSystemBackend* backend = | 322 SyncFileSystemBackend* backend = |
323 SyncFileSystemBackend::GetBackend(origin_to_contexts_[origin]); | 323 SyncFileSystemBackend::GetBackend(origin_to_contexts_[origin]); |
324 DCHECK(backend); | 324 DCHECK(backend); |
325 DCHECK(backend->change_tracker()); | 325 DCHECK(backend->change_tracker()); |
326 origin_change_map_.SetOriginChangeCount( | 326 origin_change_map_.SetOriginChangeCount( |
327 origin, backend->change_tracker()->num_changes()); | 327 origin, backend->change_tracker()->num_changes()); |
328 } | 328 } |
329 if (!need_notification) | 329 if (!need_notification) |
330 return; | 330 return; |
331 int64_t num_changes = origin_change_map_.GetTotalChangeCount(); | 331 int64_t num_changes = origin_change_map_.GetTotalChangeCount(); |
332 FOR_EACH_OBSERVER(Observer, change_observers_, | 332 FOR_EACH_OBSERVER(Observer, change_observers_, |
333 OnLocalChangeAvailable(num_changes)); | 333 OnLocalChangeAvailable(num_changes)); |
334 } | 334 } |
335 | 335 |
336 void LocalFileSyncService::SetOriginEnabled(const GURL& origin, bool enabled) { | 336 void LocalFileSyncService::SetOriginEnabled(const GURL& origin, bool enabled) { |
337 if (!ContainsKey(origin_to_contexts_, origin)) | 337 if (!base::ContainsKey(origin_to_contexts_, origin)) |
338 return; | 338 return; |
339 origin_change_map_.SetOriginEnabled(origin, enabled); | 339 origin_change_map_.SetOriginEnabled(origin, enabled); |
340 } | 340 } |
341 | 341 |
342 LocalFileSyncService::LocalFileSyncService(Profile* profile, | 342 LocalFileSyncService::LocalFileSyncService(Profile* profile, |
343 leveldb::Env* env_override) | 343 leveldb::Env* env_override) |
344 : profile_(profile), | 344 : profile_(profile), |
345 sync_context_(new LocalFileSyncContext( | 345 sync_context_(new LocalFileSyncContext( |
346 profile_->GetPath(), | 346 profile_->GetPath(), |
347 env_override, | 347 env_override, |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 } | 461 } |
462 | 462 |
463 if (status == SYNC_FILE_ERROR_NOT_FOUND && | 463 if (status == SYNC_FILE_ERROR_NOT_FOUND && |
464 processed_change.change() == FileChange::FILE_CHANGE_DELETE) { | 464 processed_change.change() == FileChange::FILE_CHANGE_DELETE) { |
465 // This must be ok (and could happen). | 465 // This must be ok (and could happen). |
466 status = SYNC_STATUS_OK; | 466 status = SYNC_STATUS_OK; |
467 } | 467 } |
468 | 468 |
469 const FileSystemURL& url = sync_file_info.url; | 469 const FileSystemURL& url = sync_file_info.url; |
470 if (status != SYNC_STATUS_OK || changes.empty()) { | 470 if (status != SYNC_STATUS_OK || changes.empty()) { |
471 DCHECK(ContainsKey(origin_to_contexts_, url.origin())); | 471 DCHECK(base::ContainsKey(origin_to_contexts_, url.origin())); |
472 sync_context_->FinalizeSnapshotSync( | 472 sync_context_->FinalizeSnapshotSync( |
473 origin_to_contexts_[url.origin()], url, status, | 473 origin_to_contexts_[url.origin()], url, status, |
474 base::Bind(callback, status, url)); | 474 base::Bind(callback, status, url)); |
475 return; | 475 return; |
476 } | 476 } |
477 | 477 |
478 FileChange next_change = changes.front(); | 478 FileChange next_change = changes.front(); |
479 GetLocalChangeProcessor(url)->ApplyLocalChange( | 479 GetLocalChangeProcessor(url)->ApplyLocalChange( |
480 changes.front(), | 480 changes.front(), |
481 sync_file_info.local_file_path, | 481 sync_file_info.local_file_path, |
482 sync_file_info.metadata, | 482 sync_file_info.metadata, |
483 url, | 483 url, |
484 base::Bind(&LocalFileSyncService::ProcessNextChangeForURL, | 484 base::Bind(&LocalFileSyncService::ProcessNextChangeForURL, |
485 AsWeakPtr(), callback, | 485 AsWeakPtr(), callback, |
486 base::Passed(&snapshot), sync_file_info, | 486 base::Passed(&snapshot), sync_file_info, |
487 next_change, changes.PopAndGetNewList())); | 487 next_change, changes.PopAndGetNewList())); |
488 } | 488 } |
489 | 489 |
490 LocalChangeProcessor* LocalFileSyncService::GetLocalChangeProcessor( | 490 LocalChangeProcessor* LocalFileSyncService::GetLocalChangeProcessor( |
491 const FileSystemURL& url) { | 491 const FileSystemURL& url) { |
492 if (!get_local_change_processor_.is_null()) | 492 if (!get_local_change_processor_.is_null()) |
493 return get_local_change_processor_.Run(url.origin()); | 493 return get_local_change_processor_.Run(url.origin()); |
494 DCHECK(local_change_processor_); | 494 DCHECK(local_change_processor_); |
495 return local_change_processor_; | 495 return local_change_processor_; |
496 } | 496 } |
497 | 497 |
498 } // namespace sync_file_system | 498 } // namespace sync_file_system |
OLD | NEW |