14ee2ad04344446e610172a0e73949212923014dfSebastian Redl// Copyright 2013 The Chromium Authors. All rights reserved. 22cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// Use of this source code is governed by a BSD-style license that can be 32cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// found in the LICENSE file. 42cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 52cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "chrome/browser/sync_file_system/local/local_file_sync_service.h" 62cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 72cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "base/single_thread_task_runner.h" 82cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "base/stl_util.h" 92cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "base/thread_task_runner_handle.h" 10a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl#include "chrome/browser/extensions/extension_util.h" 112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "chrome/browser/profiles/profile.h" 122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "chrome/browser/sync_file_system/file_change.h" 132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "chrome/browser/sync_file_system/local/local_file_change_tracker.h" 147faa2ec03a7ef120ac165bb45b6c70a8b20c9f1cSebastian Redl#include "chrome/browser/sync_file_system/local/local_file_sync_context.h" 150eca89e9890db4d8336ce762a5b359a1d58ca02bArgyrios Kyrtzidis#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" 16e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor#include "chrome/browser/sync_file_system/local_change_processor.h" 17e737f5041a36d0befb39ffeed8d50ba15916d3daDouglas Gregor#include "chrome/browser/sync_file_system/logger.h" 182cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "chrome/browser/sync_file_system/sync_file_metadata.h" 192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "content/public/browser/browser_context.h" 202cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "content/public/browser/browser_thread.h" 212a7fb27913999d132cf9e10e03dc5271faa2e9d3John McCall#include "content/public/browser/site_instance.h" 2289eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis#include "content/public/browser/storage_partition.h" 230b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor#include "extensions/browser/extension_registry.h" 247a1fad38256eb4c5129359be85ba1ea1678eb5c9John McCall#include "extensions/common/extension_set.h" 252cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "storage/browser/fileapi/file_system_context.h" 26a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall#include "storage/browser/fileapi/file_system_url.h" 276ab7cd853e9c15cf986a8a7c3db1f8d20e275409Sebastian Redl#include "storage/common/blob/scoped_file.h" 287c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattner#include "url/gurl.h" 296a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor 307c5d24efcd2e505b5739f7def08dfe25ce59a1b2Chris Lattnerusing content::BrowserThread; 3183d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroffusing storage::FileSystemURL; 3214f79002e58556798e86168c63e48d533287eda5Douglas Gregor 3310e286aa8d39fb51a21412850265d9dae74613eeChris Lattnernamespace sync_file_system { 343251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor 3514f79002e58556798e86168c63e48d533287eda5Douglas Gregornamespace { 36bd94500d3aa60092fb0f1e90f53fb0d03fa502a8Douglas Gregor 372bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregorvoid PrepareForProcessRemoteChangeCallbackAdapter( 38ab41e63821dc60ad144d0684df8d79a9eef86b75Douglas Gregor const RemoteChangeProcessor::PrepareChangeCallback& callback, 390a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor SyncStatusCode status, 4017fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor const LocalFileSyncInfo& sync_file_info, 4117fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor storage::ScopedFile snapshot) { 422596e429a61602312bdd149786045b8a90cd2d10Daniel Dunbar callback.Run(status, sync_file_info.metadata, sync_file_info.changes); 432cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 44fbfd180495e7800975c6d9bdc6d24e706ef70e34Michael J. Spencer 4514f79002e58556798e86168c63e48d533287eda5Douglas Gregorvoid InvokeCallbackOnNthInvocation(int* count, const base::Closure& callback) { 4603013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer --*count; 47f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor if (*count <= 0) 483c304bd9ec2b4611572d4cbae9e1727bbecb5dc9Chris Lattner callback.Run(); 49cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor} 50f62d43d2afe1960755a1b5813cae1e5983bcac1bDouglas Gregor 512cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} // namespace 528538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl 532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas GregorLocalFileSyncService::OriginChangeMap::OriginChangeMap() 54ade5000c8763f4bec41f452d7efa3a9b2a6d4712Sebastian Redl : next_(change_count_map_.end()) {} 555f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerLocalFileSyncService::OriginChangeMap::~OriginChangeMap() {} 565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner 575f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerbool LocalFileSyncService::OriginChangeMap::NextOriginToProcess(GURL* origin) { 586e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer DCHECK(origin); 59ade5000c8763f4bec41f452d7efa3a9b2a6d4712Sebastian Redl if (change_count_map_.empty()) 606e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer return false; 616e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer Map::iterator begin = next_; 625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner do { 635f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (next_ == change_count_map_.end()) 646e089c687cc2b914c46859ab7e46fe4c3c6b0afbBenjamin Kramer next_ = change_count_map_.begin(); 65ade5000c8763f4bec41f452d7efa3a9b2a6d4712Sebastian Redl DCHECK_NE(0, next_->second); 66ade5000c8763f4bec41f452d7efa3a9b2a6d4712Sebastian Redl *origin = next_++->first; 672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (!ContainsKey(disabled_origins_, *origin)) 682cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor return true; 692cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } while (next_ != begin); 7012b1c7615d4f9a2edc544be499f895f16ac100edChris Lattner return false; 712cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 723397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 73a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redlint64 LocalFileSyncService::OriginChangeMap::GetTotalChangeCount() const { 7489eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis int64 num_changes = 0; 752cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor for (Map::const_iterator iter = change_count_map_.begin(); 762cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor iter != change_count_map_.end(); ++iter) { 772cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (ContainsKey(disabled_origins_, iter->first)) 788538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl continue; 792cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor num_changes += iter->second; 8089eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis } 818538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl return num_changes; 822cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid LocalFileSyncService::OriginChangeMap::SetOriginChangeCount( 852cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const GURL& origin, int64 changes) { 862cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (changes != 0) { 872cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor change_count_map_[origin] = changes; 882cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor return; 892cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 902cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor Map::iterator found = change_count_map_.find(origin); 912cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (found != change_count_map_.end()) { 922cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (next_ == found) 933397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl ++next_; 94b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie change_count_map_.erase(found); 952cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 962cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 973397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 982cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid LocalFileSyncService::OriginChangeMap::SetOriginEnabled( 998538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl const GURL& origin, bool enabled) { 1002cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (enabled) 1012cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor disabled_origins_.erase(origin); 1023397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl else 1032cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor disabled_origins_.insert(origin); 1048538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl} 1052cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1062cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// LocalFileSyncService ------------------------------------------------------- 1073397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpscoped_ptr<LocalFileSyncService> LocalFileSyncService::Create( 1098538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl Profile* profile) { 1102cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor return make_scoped_ptr(new LocalFileSyncService(profile, NULL)); 1112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1123397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 113df1550fc59b51681d37225934fe4e3acac321621Richard Smithscoped_ptr<LocalFileSyncService> LocalFileSyncService::CreateForTesting( 114df1550fc59b51681d37225934fe4e3acac321621Richard Smith Profile* profile, 1158538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl leveldb::Env* env) { 1162cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor scoped_ptr<LocalFileSyncService> sync_service( 1172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor new LocalFileSyncService(profile, env)); 1183397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl sync_service->sync_context_->set_mock_notify_changes_duration_in_sec(0); 119df1550fc59b51681d37225934fe4e3acac321621Richard Smith return sync_service.Pass(); 1208538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl} 1212cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1222cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas GregorLocalFileSyncService::~LocalFileSyncService() { 1233397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 1251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1268538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redlvoid LocalFileSyncService::Shutdown() { 1272cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor sync_context_->RemoveOriginChangeObserver(this); 1282cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor sync_context_->ShutdownOnUIThread(); 1293397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl profile_ = NULL; 1302cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1312cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1320953e767ff7817f97b3ab20896b229891eeff45bJohn McCallvoid LocalFileSyncService::MaybeInitializeFileSystemContext( 1332cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const GURL& app_origin, 1342cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor storage::FileSystemContext* file_system_context, 1353397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl const SyncStatusCallback& callback) { 1362cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor sync_context_->MaybeInitializeFileSystemContext( 1372cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor app_origin, file_system_context, 1388538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl base::Bind(&LocalFileSyncService::DidInitializeFileSystemContext, 1392cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor AsWeakPtr(), app_origin, 1402cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor make_scoped_refptr(file_system_context), callback)); 1413397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl} 1422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1438538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redlvoid LocalFileSyncService::AddChangeObserver(Observer* observer) { 1442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor change_observers_.AddObserver(observer); 1452cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1463397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 1472cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid LocalFileSyncService::RegisterURLForWaitingSync( 1487e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor const FileSystemURL& url, 1497e7eb3da052a6d80ddf2377cab0384c798f73f75Douglas Gregor const base::Closure& on_syncable_callback) { 150c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor sync_context_->RegisterURLForWaitingSync(url, on_syncable_callback); 1518538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl} 1522cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid LocalFileSyncService::ProcessLocalChange( 1543397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl const SyncFileCallback& callback) { 1552cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // Pick an origin to process next. 1562cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor GURL origin; 157e86d78cf4754a6aef2cf9a33d847aa15338e276fBob Wilson if (!origin_change_map_.NextOriginToProcess(&origin)) { 1588538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl callback.Run(SYNC_STATUS_NO_CHANGE_TO_SYNC, FileSystemURL()); 1592cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor return; 1602cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 1613397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl DCHECK(local_sync_callback_.is_null()); 1622cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor DCHECK(!origin.is_empty()); 1638538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl DCHECK(ContainsKey(origin_to_contexts_, origin)); 1642cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1652cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor DVLOG(1) << "Starting ProcessLocalChange"; 1663397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 1672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor local_sync_callback_ = callback; 168264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola 169264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola sync_context_->GetFileForLocalSync( 170a49218e17bcbb1acde0245773173e2c0c42f4f19Eli Friedman origin_to_contexts_[origin], 171425ef72306d4ff6b3698b744353e5f0e56b4b884Rafael Espindola base::Bind(&LocalFileSyncService::DidGetFileForLocalSync, 172ab8bbf4ebd3e3e6eab913cb044772a62b7581941Douglas Gregor AsWeakPtr())); 173264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola} 174f85e193739c953358c865005855253af4f68a497John McCall 1752cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid LocalFileSyncService::SetLocalChangeProcessor( 1762cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor LocalChangeProcessor* local_change_processor) { 1773397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl local_change_processor_ = local_change_processor; 1782cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1798538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl 1802cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid LocalFileSyncService::SetLocalChangeProcessorCallback( 1812cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const GetLocalChangeProcessorCallback& get_local_change_processor) { 1823397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl get_local_change_processor_ = get_local_change_processor; 1832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 1842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 1852cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid LocalFileSyncService::HasPendingLocalChanges( 1862cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const FileSystemURL& url, 1872cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const HasPendingLocalChangeCallback& callback) { 1882cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (!ContainsKey(origin_to_contexts_, url.origin())) { 189c938c1668b4fd12af154e965dd935a89e4801a70Douglas Gregor base::ThreadTaskRunnerHandle::Get()->PostTask( 19060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl FROM_HERE, 19160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl base::Bind(callback, SYNC_FILE_ERROR_INVALID_URL, false)); 19260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return; 19360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl } 19460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl sync_context_->HasPendingLocalChanges( 19560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl origin_to_contexts_[url.origin()], url, callback); 19660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl} 19760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 1988538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redlvoid LocalFileSyncService::PromoteDemotedChanges( 1992cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const base::Closure& callback) { 2002cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (origin_to_contexts_.empty()) { 2013397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl callback.Run(); 202ed97649e9574b9d854fa4d6109c9333ae0993554John McCall return; 2038538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl } 204ed97649e9574b9d854fa4d6109c9333ae0993554John McCall 205ed97649e9574b9d854fa4d6109c9333ae0993554John McCall base::Closure completion_callback = 2063397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl base::Bind(&InvokeCallbackOnNthInvocation, 2072cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor base::Owned(new int(origin_to_contexts_.size())), callback); 2089763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis for (OriginToContext::iterator iter = origin_to_contexts_.begin(); 2099763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis iter != origin_to_contexts_.end(); ++iter) 2108538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl sync_context_->PromoteDemotedChanges(iter->first, iter->second, 2112cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor completion_callback); 2122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 2133397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 214c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregorvoid LocalFileSyncService::GetLocalFileMetadata( 2158538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl const FileSystemURL& url, const SyncFileMetadataCallback& callback) { 2162cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor DCHECK(ContainsKey(origin_to_contexts_, url.origin())); 2172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor sync_context_->GetFileMetadata(origin_to_contexts_[url.origin()], 2183397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl url, callback); 2192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 2208538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl 2212cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorvoid LocalFileSyncService::PrepareForProcessRemoteChange( 2222cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const FileSystemURL& url, 2233397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl const PrepareChangeCallback& callback) { 224395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson DVLOG(1) << "PrepareForProcessRemoteChange: " << url.DebugString(); 2258538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl 226395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson if (!ContainsKey(origin_to_contexts_, url.origin())) { 227395b475a4474f1c7574d927ad142ca0c7997cbcaAnders Carlsson // This could happen if a remote sync is triggered for the app that hasn't 228ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt // been initialized in this service. 229ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt DCHECK(profile_); 230ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt // The given url.origin() must be for valid installed app. 231ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt const extensions::Extension* extension = 232ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt extensions::ExtensionRegistry::Get(profile_) 233ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt ->enabled_extensions().GetAppByURL(url.origin()); 234ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt if (!extension) { 23534b41d939a1328f484511c6002ba2456db879a29Richard Smith util::Log( 23634b41d939a1328f484511c6002ba2456db879a29Richard Smith logging::LOG_WARNING, 23734b41d939a1328f484511c6002ba2456db879a29Richard Smith FROM_HERE, 23834b41d939a1328f484511c6002ba2456db879a29Richard Smith "PrepareForProcessRemoteChange called for non-existing origin: %s", 23934b41d939a1328f484511c6002ba2456db879a29Richard Smith url.origin().spec().c_str()); 2403397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 241be191100e034b23a3e13053757a57b7f5068c24aArgyrios Kyrtzidis // The extension has been uninstalled and this method is called 2422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor // before the remote changes for the origin are removed. 2431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump callback.Run(SYNC_STATUS_NO_CHANGE_TO_SYNC, 2442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor SyncFileMetadata(), FileChangeList()); 2452cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor return; 2462cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 2473397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl GURL site_url = 2482cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor extensions::util::GetSiteForExtensionId(extension->id(), profile_); 2498538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl DCHECK(!site_url.is_empty()); 2502cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor scoped_refptr<storage::FileSystemContext> file_system_context = 2512cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor content::BrowserContext::GetStoragePartitionForSite(profile_, site_url) 2523397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl ->GetFileSystemContext(); 2532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor MaybeInitializeFileSystemContext( 2548538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl url.origin(), 2552cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor file_system_context.get(), 2562cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor base::Bind(&LocalFileSyncService::DidInitializeForRemoteSync, 2579d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall AsWeakPtr(), 2589d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall url, 2599d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall file_system_context, 2609d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall callback)); 2619d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall return; 2629d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall } 2639d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall 2641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump DCHECK(ContainsKey(origin_to_contexts_, url.origin())); 2653397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl sync_context_->PrepareForSync( 26649a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall origin_to_contexts_[url.origin()], url, 26749a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall LocalFileSyncContext::SYNC_EXCLUSIVE, 26849a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall base::Bind(&PrepareForProcessRemoteChangeCallbackAdapter, callback)); 2698538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl} 27049a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall 27149a832bd499d6f61c23655f1fac99f0dd229756eJohn McCallvoid LocalFileSyncService::ApplyRemoteChange( 27249a832bd499d6f61c23655f1fac99f0dd229756eJohn McCall const FileChange& change, 273c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor const base::FilePath& local_path, 274c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor const FileSystemURL& url, 275c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor const SyncStatusCallback& callback) { 276c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor DCHECK(ContainsKey(origin_to_contexts_, url.origin())); 277c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor util::Log(logging::LOG_VERBOSE, FROM_HERE, 278c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor "[Remote -> Local] ApplyRemoteChange: %s on %s", 279c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor change.DebugString().c_str(), 280c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor url.DebugString().c_str()); 2813397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 2822cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor sync_context_->ApplyRemoteChange( 283be191100e034b23a3e13053757a57b7f5068c24aArgyrios Kyrtzidis origin_to_contexts_[url.origin()], 28490b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis change, local_path, url, 28590b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis base::Bind(&LocalFileSyncService::DidApplyRemoteChange, AsWeakPtr(), 28690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis callback)); 28790b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis} 28890b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis 2893e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smithvoid LocalFileSyncService::FinalizeRemoteSync( 2903e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith const FileSystemURL& url, 2919763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis bool clear_local_changes, 2929763e221e16026ddf487d2564ed349d2c874a1a1Argyrios Kyrtzidis const base::Closure& completion_callback) { 2938538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl DCHECK(ContainsKey(origin_to_contexts_, url.origin())); 29490b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis sync_context_->FinalizeExclusiveSync( 29590b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis origin_to_contexts_[url.origin()], 29690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis url, clear_local_changes, completion_callback); 2973397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl} 298ae8b17f1d5d303af53db5a4f4a375ea6b9356566Argyrios Kyrtzidis 299ae8b17f1d5d303af53db5a4f4a375ea6b9356566Argyrios Kyrtzidisvoid LocalFileSyncService::RecordFakeLocalChange( 300ae8b17f1d5d303af53db5a4f4a375ea6b9356566Argyrios Kyrtzidis const FileSystemURL& url, 3018538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl const FileChange& change, 30290b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis const SyncStatusCallback& callback) { 30390b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis DCHECK(ContainsKey(origin_to_contexts_, url.origin())); 30490b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis sync_context_->RecordFakeLocalChange(origin_to_contexts_[url.origin()], 3053397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl url, change, callback); 30690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis} 30790b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis 308b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikievoid LocalFileSyncService::OnChangesAvailableInOrigins( 30990b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis const std::set<GURL>& origins) { 31090b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis bool need_notification = false; 31190b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis for (std::set<GURL>::const_iterator iter = origins.begin(); 3123397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl iter != origins.end(); ++iter) { 31390b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis const GURL& origin = *iter; 31490b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis if (!ContainsKey(origin_to_contexts_, origin)) { 31590b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis // This could happen if this is called for apps/origins that haven't 3164fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth // been initialized yet, or for apps/origins that are disabled. 3178538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl // (Local change tracker could call this for uninitialized origins 31890b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis // while it's reading dirty files from the database in the 31990b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis // initialization phase.) 32090b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis pending_origins_with_changes_.insert(origin); 3213397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl continue; 3228dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis } 3238dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis need_notification = true; 3248dfbd8b252ba4e6cf4b7a3422f6ef0ca21312dfeArgyrios Kyrtzidis SyncFileSystemBackend* backend = 325f48d45e3e36c132bdee3373beec4e8b19ae3f9c4Argyrios Kyrtzidis SyncFileSystemBackend::GetBackend(origin_to_contexts_[origin]); 326f48d45e3e36c132bdee3373beec4e8b19ae3f9c4Argyrios Kyrtzidis DCHECK(backend); 327f48d45e3e36c132bdee3373beec4e8b19ae3f9c4Argyrios Kyrtzidis DCHECK(backend->change_tracker()); 3288538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl origin_change_map_.SetOriginChangeCount( 32990b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis origin, backend->change_tracker()->num_changes()); 33090b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis } 33190b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis if (!need_notification) 3323397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl return; 33390b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis int64 num_changes = origin_change_map_.GetTotalChangeCount(); 3343acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis FOR_EACH_OBSERVER(Observer, change_observers_, 3353acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis OnLocalChangeAvailable(num_changes)); 3363acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis} 3373acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis 3383acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidisvoid LocalFileSyncService::SetOriginEnabled(const GURL& origin, bool enabled) { 3393acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis if (!ContainsKey(origin_to_contexts_, origin)) 3403acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis return; 3418538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl origin_change_map_.SetOriginEnabled(origin, enabled); 3422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} 3432cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor 3447536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas GregorLocalFileSyncService::LocalFileSyncService(Profile* profile, 3457536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor leveldb::Env* env_override) 346cded4f649cd4b7ba7d461c25c6482ef52b8d3a2aDouglas Gregor : profile_(profile), 347cded4f649cd4b7ba7d461c25c6482ef52b8d3a2aDouglas Gregor sync_context_(new LocalFileSyncContext( 348cded4f649cd4b7ba7d461c25c6482ef52b8d3a2aDouglas Gregor profile_->GetPath(), 349cded4f649cd4b7ba7d461c25c6482ef52b8d3a2aDouglas Gregor env_override, 3507536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI).get(), 3517536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO) 3527536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor .get())), 353075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara local_change_processor_(NULL) { 354075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 355075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara sync_context_->AddOriginChangeObserver(this); 356075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara} 357075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara 3583397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redlvoid LocalFileSyncService::DidInitializeFileSystemContext( 359465d41b92b2c862f3062c412a0538db65c6a2661Abramo Bagnara const GURL& app_origin, 3603acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis storage::FileSystemContext* file_system_context, 3613acad62a239448bef0f5848b2a0d5f7dfefd3d14Argyrios Kyrtzidis const SyncStatusCallback& callback, 3628538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl SyncStatusCode status) { 3632cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor if (status != SYNC_STATUS_OK) { 3642cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor callback.Run(status); 3653397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl return; 3663cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall } 36731f17ecbef57b5679c017c375db330546b7b5145John McCall DCHECK(file_system_context); 3688538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl origin_to_contexts_[app_origin] = file_system_context; 3693cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall 3703cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall if (pending_origins_with_changes_.find(app_origin) != 3713397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl pending_origins_with_changes_.end()) { 372deacbdca554298ccdf636f19c6094a8825ec6b34Douglas Gregor // We have remaining changes for the origin. 3738538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl pending_origins_with_changes_.erase(app_origin); 374c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall SyncFileSystemBackend* backend = 375c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall SyncFileSystemBackend::GetBackend(file_system_context); 3763397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl DCHECK(backend); 377c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall DCHECK(backend->change_tracker()); 3782cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor origin_change_map_.SetOriginChangeCount( 379c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall app_origin, backend->change_tracker()->num_changes()); 380446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff int64 num_changes = origin_change_map_.GetTotalChangeCount(); 381446ee4eb4fc4c705a59365252df7a5c253daafa1Steve Naroff FOR_EACH_OBSERVER(Observer, change_observers_, 3828538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl OnLocalChangeAvailable(num_changes)); 3832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor } 3842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor callback.Run(status); 385d1b3c2dd5bc1f3103bee6137957aa7c5f8f2f0bcSteve Naroff} 3863397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl 3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid LocalFileSyncService::DidInitializeForRemoteSync( 3888538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl const FileSystemURL& url, 3892cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor storage::FileSystemContext* file_system_context, 3902cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor const PrepareChangeCallback& callback, 391b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman SyncStatusCode status) { 392b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman if (status != SYNC_STATUS_OK) { 393b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman DVLOG(1) << "FileSystemContext initialization failed for remote sync:" 394b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman << url.DebugString() << " status=" << status 395b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman << " (" << SyncStatusCodeToString(status) << ")"; 396b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman callback.Run(status, SyncFileMetadata(), FileChangeList()); 397a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall return; 398a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall } 399a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall origin_to_contexts_[url.origin()] = file_system_context; 400a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl PrepareForProcessRemoteChange(url, callback); 40189eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis} 402a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall 403a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCallvoid LocalFileSyncService::RunLocalSyncCallback( 40489eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis SyncStatusCode status, 405a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall const FileSystemURL& url) { 406a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall DVLOG(1) << "Local sync is finished with: " << status 40751bd803fbdade51d674598ed45da3d54190a656cJohn McCall << " on " << url.DebugString(); 408a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall DCHECK(!local_sync_callback_.is_null()); 40951bd803fbdade51d674598ed45da3d54190a656cJohn McCall SyncFileCallback callback = local_sync_callback_; 410a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall local_sync_callback_.Reset(); 411a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall callback.Run(status, url); 41251bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 41351bd803fbdade51d674598ed45da3d54190a656cJohn McCall 414a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCallvoid LocalFileSyncService::DidApplyRemoteChange( 415a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall const SyncStatusCallback& callback, 416a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall SyncStatusCode status) { 417a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall util::Log(logging::LOG_VERBOSE, FROM_HERE, 41851bd803fbdade51d674598ed45da3d54190a656cJohn McCall "[Remote -> Local] ApplyRemoteChange finished --> %s", 41951bd803fbdade51d674598ed45da3d54190a656cJohn McCall SyncStatusCodeToString(status)); 42051bd803fbdade51d674598ed45da3d54190a656cJohn McCall callback.Run(status); 42151bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 422ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor 423ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregorvoid LocalFileSyncService::DidGetFileForLocalSync( 424ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor SyncStatusCode status, 425ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor const LocalFileSyncInfo& sync_file_info, 426ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor storage::ScopedFile snapshot) { 427ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor DCHECK(!local_sync_callback_.is_null()); 428ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor if (status != SYNC_STATUS_OK) { 42951bd803fbdade51d674598ed45da3d54190a656cJohn McCall RunLocalSyncCallback(status, sync_file_info.url); 43051bd803fbdade51d674598ed45da3d54190a656cJohn McCall return; 43151bd803fbdade51d674598ed45da3d54190a656cJohn McCall } 43251bd803fbdade51d674598ed45da3d54190a656cJohn McCall if (sync_file_info.changes.empty()) { 43351bd803fbdade51d674598ed45da3d54190a656cJohn McCall // There's a slight chance this could happen. 43451bd803fbdade51d674598ed45da3d54190a656cJohn McCall SyncFileCallback callback = local_sync_callback_; 43551bd803fbdade51d674598ed45da3d54190a656cJohn McCall local_sync_callback_.Reset(); 43651bd803fbdade51d674598ed45da3d54190a656cJohn McCall ProcessLocalChange(callback); 43751bd803fbdade51d674598ed45da3d54190a656cJohn McCall return; 43851bd803fbdade51d674598ed45da3d54190a656cJohn McCall } 43951bd803fbdade51d674598ed45da3d54190a656cJohn McCall 44051bd803fbdade51d674598ed45da3d54190a656cJohn McCall FileChange next_change = sync_file_info.changes.front(); 44151bd803fbdade51d674598ed45da3d54190a656cJohn McCall DVLOG(1) << "ProcessLocalChange: " << sync_file_info.url.DebugString() 44251bd803fbdade51d674598ed45da3d54190a656cJohn McCall << " change:" << next_change.DebugString(); 44351bd803fbdade51d674598ed45da3d54190a656cJohn McCall 44451bd803fbdade51d674598ed45da3d54190a656cJohn McCall GetLocalChangeProcessor(sync_file_info.url)->ApplyLocalChange( 44551bd803fbdade51d674598ed45da3d54190a656cJohn McCall next_change, 44651bd803fbdade51d674598ed45da3d54190a656cJohn McCall sync_file_info.local_file_path, 447b6ab6c1ca733fda2302a1c5066bdfc6218c89e41Abramo Bagnara sync_file_info.metadata, 44851bd803fbdade51d674598ed45da3d54190a656cJohn McCall sync_file_info.url, 44951bd803fbdade51d674598ed45da3d54190a656cJohn McCall base::Bind(&LocalFileSyncService::ProcessNextChangeForURL, 45051bd803fbdade51d674598ed45da3d54190a656cJohn McCall AsWeakPtr(), base::Passed(&snapshot), sync_file_info, 45151bd803fbdade51d674598ed45da3d54190a656cJohn McCall next_change, sync_file_info.changes.PopAndGetNewList())); 45251bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 45351bd803fbdade51d674598ed45da3d54190a656cJohn McCall 45451bd803fbdade51d674598ed45da3d54190a656cJohn McCallvoid LocalFileSyncService::ProcessNextChangeForURL( 45551bd803fbdade51d674598ed45da3d54190a656cJohn McCall storage::ScopedFile snapshot, 45651bd803fbdade51d674598ed45da3d54190a656cJohn McCall const LocalFileSyncInfo& sync_file_info, 45751bd803fbdade51d674598ed45da3d54190a656cJohn McCall const FileChange& processed_change, 45851bd803fbdade51d674598ed45da3d54190a656cJohn McCall const FileChangeList& changes, 45951bd803fbdade51d674598ed45da3d54190a656cJohn McCall SyncStatusCode status) { 46051bd803fbdade51d674598ed45da3d54190a656cJohn McCall DVLOG(1) << "Processed one local change: " 46151bd803fbdade51d674598ed45da3d54190a656cJohn McCall << sync_file_info.url.DebugString() 46251bd803fbdade51d674598ed45da3d54190a656cJohn McCall << " change:" << processed_change.DebugString() 46351bd803fbdade51d674598ed45da3d54190a656cJohn McCall << " status:" << status; 46451bd803fbdade51d674598ed45da3d54190a656cJohn McCall 46551bd803fbdade51d674598ed45da3d54190a656cJohn McCall if (status == SYNC_STATUS_RETRY) { 46651bd803fbdade51d674598ed45da3d54190a656cJohn McCall GetLocalChangeProcessor(sync_file_info.url)->ApplyLocalChange( 46751bd803fbdade51d674598ed45da3d54190a656cJohn McCall processed_change, 46851bd803fbdade51d674598ed45da3d54190a656cJohn McCall sync_file_info.local_file_path, 46951bd803fbdade51d674598ed45da3d54190a656cJohn McCall sync_file_info.metadata, 47051bd803fbdade51d674598ed45da3d54190a656cJohn McCall sync_file_info.url, 47151bd803fbdade51d674598ed45da3d54190a656cJohn McCall base::Bind(&LocalFileSyncService::ProcessNextChangeForURL, 47251bd803fbdade51d674598ed45da3d54190a656cJohn McCall AsWeakPtr(), base::Passed(&snapshot), 47351bd803fbdade51d674598ed45da3d54190a656cJohn McCall sync_file_info, processed_change, changes)); 47451bd803fbdade51d674598ed45da3d54190a656cJohn McCall return; 47551bd803fbdade51d674598ed45da3d54190a656cJohn McCall } 47651bd803fbdade51d674598ed45da3d54190a656cJohn McCall 47751bd803fbdade51d674598ed45da3d54190a656cJohn McCall if (status == SYNC_FILE_ERROR_NOT_FOUND && 47851bd803fbdade51d674598ed45da3d54190a656cJohn McCall processed_change.change() == FileChange::FILE_CHANGE_DELETE) { 47951bd803fbdade51d674598ed45da3d54190a656cJohn McCall // This must be ok (and could happen). 480796aa443ab5ed036f42ef33fed629e1b4b34871bAbramo Bagnara status = SYNC_STATUS_OK; 481796aa443ab5ed036f42ef33fed629e1b4b34871bAbramo Bagnara } 482dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor 48351bd803fbdade51d674598ed45da3d54190a656cJohn McCall const FileSystemURL& url = sync_file_info.url; 48451bd803fbdade51d674598ed45da3d54190a656cJohn McCall if (status != SYNC_STATUS_OK || changes.empty()) { 48551bd803fbdade51d674598ed45da3d54190a656cJohn McCall DCHECK(ContainsKey(origin_to_contexts_, url.origin())); 48651bd803fbdade51d674598ed45da3d54190a656cJohn McCall sync_context_->FinalizeSnapshotSync( 48751bd803fbdade51d674598ed45da3d54190a656cJohn McCall origin_to_contexts_[url.origin()], url, status, 48851bd803fbdade51d674598ed45da3d54190a656cJohn McCall base::Bind(&LocalFileSyncService::RunLocalSyncCallback, 48951bd803fbdade51d674598ed45da3d54190a656cJohn McCall AsWeakPtr(), status, url)); 49051bd803fbdade51d674598ed45da3d54190a656cJohn McCall return; 49151bd803fbdade51d674598ed45da3d54190a656cJohn McCall } 492ed97649e9574b9d854fa4d6109c9333ae0993554John McCall 493ed97649e9574b9d854fa4d6109c9333ae0993554John McCall FileChange next_change = changes.front(); 494ed97649e9574b9d854fa4d6109c9333ae0993554John McCall GetLocalChangeProcessor(url)->ApplyLocalChange( 49551bd803fbdade51d674598ed45da3d54190a656cJohn McCall changes.front(), 49651bd803fbdade51d674598ed45da3d54190a656cJohn McCall sync_file_info.local_file_path, 49751bd803fbdade51d674598ed45da3d54190a656cJohn McCall sync_file_info.metadata, 49851bd803fbdade51d674598ed45da3d54190a656cJohn McCall url, 499cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall base::Bind(&LocalFileSyncService::ProcessNextChangeForURL, 500cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall AsWeakPtr(), base::Passed(&snapshot), sync_file_info, 501cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall next_change, changes.PopAndGetNewList())); 50251bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 50351bd803fbdade51d674598ed45da3d54190a656cJohn McCall 504cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCallLocalChangeProcessor* LocalFileSyncService::GetLocalChangeProcessor( 505cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall const FileSystemURL& url) { 506cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall if (!get_local_change_processor_.is_null()) 507cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall return get_local_change_processor_.Run(url.origin()); 50851bd803fbdade51d674598ed45da3d54190a656cJohn McCall DCHECK(local_change_processor_); 50951bd803fbdade51d674598ed45da3d54190a656cJohn McCall return local_change_processor_; 51051bd803fbdade51d674598ed45da3d54190a656cJohn McCall} 511a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall 512ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt} // namespace sync_file_system 513ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt