| 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 |