190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_sync_context.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/platform_file.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/single_thread_task_runner.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/task_runner_util.h" 132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/file_change.h" 142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_change_tracker.h" 152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_origin_change_observer.h" 162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" 172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/syncable_file_operation_runner.h" 182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_file_metadata.h" 192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/syncable_file_system_util.h" 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_context.h" 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_file_util.h" 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_operation_context.h" 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/fileapi/file_system_operation_runner.h" 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/fileapi/file_system_util.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemContext; 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemFileUtil; 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemOperation; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemOperationContext; 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemURL; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sync_file_system { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxConcurrentSyncableOperation = 3; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kNotifyChangesDurationInSec = 1; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxURLsToFetchForLocalSync = 5; 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LocalFileSyncContext::LocalFileSyncContext( 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SingleThreadTaskRunner* ui_task_runner, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SingleThreadTaskRunner* io_task_runner) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ui_task_runner_(ui_task_runner), 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_task_runner_(io_task_runner), 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shutdown_on_ui_(false), 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mock_notify_changes_duration_in_sec_(-1) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::MaybeInitializeFileSystemContext( 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& source_url, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemContext* file_system_context, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SyncStatusCallback& callback) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ContainsKey(file_system_contexts_, file_system_context)) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The context has been already initialized. Just dispatch the callback 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with SYNC_STATUS_OK. 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui_task_runner_->PostTask(FROM_HERE, 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_STATUS_OK)); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StatusCallbackQueue& callback_queue = 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_initialize_callbacks_[file_system_context]; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_queue.push_back(callback); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (callback_queue.size() > 1) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_task_runner_->PostTask( 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::InitializeFileSystemContextOnIOThread, 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this, source_url, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_scoped_refptr(file_system_context))); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::ShutdownOnUIThread() { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shutdown_on_ui_ = true; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_task_runner_->PostTask( 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::ShutdownOnIOThread, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this)); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::GetFileForLocalSync( 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemContext* file_system_context, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LocalFileSyncInfoCallback& callback) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(file_system_context); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::deque<FileSystemURL>* urls = new std::deque<FileSystemURL>; 95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) file_system_context->default_file_task_runner()->PostTaskAndReply( 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::GetNextURLsForSyncOnFileThread, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, make_scoped_refptr(file_system_context), 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(urls)), 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::TryPrepareForLocalSync, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, make_scoped_refptr(file_system_context), 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Owned(urls), callback)); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LocalFileSyncContext::ClearChangesForURL( 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemContext* file_system_context, 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Closure& done_callback) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is initially called on UI thread and to be relayed to FILE thread. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(file_system_context); 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!file_system_context->default_file_task_runner()-> 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunsTasksOnCurrentThread()) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) file_system_context->default_file_task_runner()->PostTask( 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&LocalFileSyncContext::ClearChangesForURL, 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, make_scoped_refptr(file_system_context), 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url, done_callback)); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend* backend = 123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend::GetBackend(file_system_context); 124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(backend); 125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(backend->change_tracker()); 126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) backend->change_tracker()->ClearChangesForURL(url); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Call the completion callback on UI thread. 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui_task_runner_->PostTask(FROM_HERE, done_callback); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LocalFileSyncContext::ClearSyncFlagForURL(const FileSystemURL& url) { 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is initially called on UI thread and to be relayed to IO thread. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_task_runner_->PostTask( 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::EnableWritingOnIOThread, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, url)); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::PrepareForSync( 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemContext* file_system_context, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileSystemURL& url, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LocalFileSyncInfoCallback& callback) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is initially called on UI thread and to be relayed to IO thread. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!io_task_runner_->RunsTasksOnCurrentThread()) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_task_runner_->PostTask( 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::PrepareForSync, this, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_scoped_refptr(file_system_context), url, callback)); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool syncable = sync_status()->IsSyncable(url); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disable writing if it's ready to be synced. 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (syncable) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status()->StartSyncing(url); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_task_runner_->PostTask( 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::DidGetWritingStatusForSync, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, make_scoped_refptr(file_system_context), 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncable ? SYNC_STATUS_OK : 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_STATUS_FILE_BUSY, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url, callback)); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::RegisterURLForWaitingSync( 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileSystemURL& url, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& on_syncable_callback) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is initially called on UI thread and to be relayed to IO thread. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!io_task_runner_->RunsTasksOnCurrentThread()) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_task_runner_->PostTask( 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::RegisterURLForWaitingSync, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, url, on_syncable_callback)); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (sync_status()->IsSyncable(url)) { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No need to register; fire the callback now. 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_task_runner_->PostTask(FROM_HERE, on_syncable_callback); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_waiting_sync_on_io_ = url; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_syncable_callback_ = on_syncable_callback; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::ApplyRemoteChange( 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemContext* file_system_context, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileChange& change, 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& local_path, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileSystemURL& url, 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SyncStatusCallback& callback) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!io_task_runner_->RunsTasksOnCurrentThread()) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_task_runner_->PostTask( 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::ApplyRemoteChange, this, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_scoped_refptr(file_system_context), 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change, local_path, url, callback)); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!sync_status()->IsWritable(url)); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!sync_status()->IsWriting(url)); 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileSystemOperation::StatusCallback operation_callback; 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (change.change() == FileChange::FILE_CHANGE_ADD_OR_UPDATE) { 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) operation_callback = base::Bind( 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &LocalFileSyncContext::DidRemoveExistingEntryForApplyRemoteChange, 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) make_scoped_refptr(file_system_context), 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) change, 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) local_path, 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) url, 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback); 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(FileChange::FILE_CHANGE_DELETE, change.change()); 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) operation_callback = base::Bind( 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &LocalFileSyncContext::DidApplyRemoteChange, this, url, callback); 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FileSystemURL url_for_sync = CreateSyncableFileSystemURLForSync( 224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context, url); 225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context->operation_runner()->Remove( 226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) url_for_sync, true /* recursive */, operation_callback); 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void LocalFileSyncContext::DidRemoveExistingEntryForApplyRemoteChange( 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileSystemContext* file_system_context, 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const FileChange& change, 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& local_path, 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const FileSystemURL& url, 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const SyncStatusCallback& callback, 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformFileError error) { 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Remove() may fail if the target entry does not exist (which is ok), 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // so we ignore |error| here. 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!sync_status()) { 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(SYNC_FILE_ERROR_ABORT); 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!sync_status()->IsWritable(url)); 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!sync_status()->IsWriting(url)); 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FileSystemURL url_for_sync = CreateSyncableFileSystemURLForSync( 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context, url); 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileSystemOperation::StatusCallback operation_callback = base::Bind( 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &LocalFileSyncContext::DidApplyRemoteChange, this, url, callback); 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(FileChange::FILE_CHANGE_ADD_OR_UPDATE, change.change()); 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (change.file_type()) { 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case SYNC_FILE_TYPE_FILE: { 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!local_path.empty()); 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath dir_path = fileapi::VirtualPath::DirName(url.path()); 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (dir_path.empty() || 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fileapi::VirtualPath::DirName(dir_path) == dir_path) { 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Copying into the root directory. 261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context->operation_runner()->CopyInForeignFile( 262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) local_path, url_for_sync, operation_callback); 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileSystemURL dir_url = file_system_context->CreateCrackedFileSystemURL( 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) url_for_sync.origin(), 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) url_for_sync.mount_type(), 267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fileapi::VirtualPath::DirName(url_for_sync.virtual_path())); 268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context->operation_runner()->CreateDirectory( 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dir_url, 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false /* exclusive */, 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) true /* recursive */, 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&LocalFileSyncContext::DidCreateDirectoryForCopyIn, 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) make_scoped_refptr(file_system_context), 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) local_path, 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) url, 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) operation_callback)); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case SYNC_FILE_TYPE_DIRECTORY: 282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context->operation_runner()->CreateDirectory( 283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) url_for_sync, false /* exclusive */, true /* recursive */, 284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) operation_callback); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case SYNC_FILE_TYPE_UNKNOWN: 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NOTREACHED() << "File type unknown for ADD_OR_UPDATE change"; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LocalFileSyncContext::RecordFakeLocalChange( 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileSystemContext* file_system_context, 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileChange& change, 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SyncStatusCallback& callback) { 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is called on UI thread and to be relayed to FILE thread. 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(file_system_context); 298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!file_system_context->default_file_task_runner()-> 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunsTasksOnCurrentThread()) { 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) file_system_context->default_file_task_runner()->PostTask( 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&LocalFileSyncContext::RecordFakeLocalChange, 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, make_scoped_refptr(file_system_context), 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url, change, callback)); 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 309a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend* backend = 310a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend::GetBackend(file_system_context); 311a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(backend); 312a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(backend->change_tracker()); 313a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) backend->change_tracker()->MarkDirtyOnDatabase(url); 314a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) backend->change_tracker()->RecordChange(url, change); 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Fire the callback on UI thread. 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui_task_runner_->PostTask(FROM_HERE, 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_STATUS_OK)); 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::GetFileMetadata( 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemContext* file_system_context, 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileSystemURL& url, 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SyncFileMetadataCallback& callback) { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is initially called on UI thread and to be relayed to IO thread. 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!io_task_runner_->RunsTasksOnCurrentThread()) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_task_runner_->PostTask( 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::GetFileMetadata, this, 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_scoped_refptr(file_system_context), url, callback)); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FileSystemURL url_for_sync = CreateSyncableFileSystemURLForSync( 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context, url); 339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context->operation_runner()->GetMetadata( 340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) url_for_sync, base::Bind(&LocalFileSyncContext::DidGetFileMetadata, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, callback)); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LocalFileSyncContext::HasPendingLocalChanges( 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileSystemContext* file_system_context, 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const HasPendingLocalChangeCallback& callback) { 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This gets called on UI thread and relays the task on FILE thread. 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(file_system_context); 350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!file_system_context->default_file_task_runner()-> 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunsTasksOnCurrentThread()) { 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) file_system_context->default_file_task_runner()->PostTask( 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&LocalFileSyncContext::HasPendingLocalChanges, 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, make_scoped_refptr(file_system_context), 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url, callback)); 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 361a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend* backend = 362a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend::GetBackend(file_system_context); 363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(backend); 364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(backend->change_tracker()); 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileChangeList changes; 366a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) backend->change_tracker()->GetChangesForURL(url, &changes); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Fire the callback on UI thread. 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui_task_runner_->PostTask(FROM_HERE, 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_STATUS_OK, 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !changes.empty())); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::AddOriginChangeObserver( 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LocalOriginChangeObserver* observer) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_change_observers_.AddObserver(observer); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::RemoveOriginChangeObserver( 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LocalOriginChangeObserver* observer) { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_change_observers_.RemoveObserver(observer); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::WeakPtr<SyncableFileOperationRunner> 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LocalFileSyncContext::operation_runner() const { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 388b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (operation_runner_) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return operation_runner_->AsWeakPtr(); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::WeakPtr<SyncableFileOperationRunner>(); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LocalFileSyncStatus* LocalFileSyncContext::sync_status() const { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sync_status_.get(); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::OnSyncEnabled(const FileSystemURL& url) { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) origins_with_pending_changes_.insert(url.origin()); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScheduleNotifyChangesUpdatedOnIOThread(); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url_syncable_callback_.is_null() || 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status()->IsWriting(url_waiting_sync_on_io_)) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kinuko): may want to check how many pending tasks we have. 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_task_runner_->PostTask(FROM_HERE, url_syncable_callback_); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_syncable_callback_.Reset(); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::OnWriteEnabled(const FileSystemURL& url) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nothing to do for now. 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LocalFileSyncContext::~LocalFileSyncContext() { 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LocalFileSyncContext::ScheduleNotifyChangesUpdatedOnIOThread() { 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::Time::Now() > last_notified_changes_ + NotifyChangesDuration()) { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyAvailableChangesOnIOThread(); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!timer_on_io_->IsRunning()) { 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_on_io_->Start( 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, NotifyChangesDuration(), this, 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &LocalFileSyncContext::NotifyAvailableChangesOnIOThread); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::NotifyAvailableChangesOnIOThread() { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_task_runner_->PostTask( 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::NotifyAvailableChanges, 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, origins_with_pending_changes_)); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_notified_changes_ = base::Time::Now(); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origins_with_pending_changes_.clear(); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::NotifyAvailableChanges( 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::set<GURL>& origins) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(LocalOriginChangeObserver, origin_change_observers_, 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnChangesAvailableInOrigins(origins)); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::ShutdownOnIOThread() { 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operation_runner_.reset(); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status_.reset(); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_on_io_.reset(); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::InitializeFileSystemContextOnIOThread( 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& source_url, 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemContext* file_system_context) { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(file_system_context); 458a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend* backend = 459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend::GetBackend(file_system_context); 460a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(backend); 461a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!backend->change_tracker()) { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First registers the service name. 463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RegisterSyncableFileSystem(); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create and initialize LocalFileChangeTracker and call back this method 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // later again. 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<GURL>* origins_with_changes = new std::set<GURL>; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<LocalFileChangeTracker>* tracker_ptr( 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new scoped_ptr<LocalFileChangeTracker>); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::PostTaskAndReplyWithResult( 470a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) file_system_context->default_file_task_runner(), 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::InitializeChangeTrackerOnFileThread, 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, tracker_ptr, 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) make_scoped_refptr(file_system_context), 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) origins_with_changes), 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::DidInitializeChangeTrackerOnIOThread, 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, base::Owned(tracker_ptr), 478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) source_url, 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) make_scoped_refptr(file_system_context), 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Owned(origins_with_changes))); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 483b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!operation_runner_) { 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!sync_status_); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!timer_on_io_); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status_.reset(new LocalFileSyncStatus); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_on_io_.reset(new base::OneShotTimer<LocalFileSyncContext>); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operation_runner_.reset(new SyncableFileOperationRunner( 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMaxConcurrentSyncableOperation, 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status_.get())); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status_->AddObserver(this); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 493a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) backend->set_sync_context(this); 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DidInitialize(source_url, file_system_context, 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_STATUS_OK); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncStatusCode LocalFileSyncContext::InitializeChangeTrackerOnFileThread( 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<LocalFileChangeTracker>* tracker_ptr, 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileSystemContext* file_system_context, 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<GURL>* origins_with_changes) { 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(file_system_context); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tracker_ptr); 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(origins_with_changes); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracker_ptr->reset(new LocalFileChangeTracker( 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_system_context->partition_path(), 507a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) file_system_context->default_file_task_runner())); 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SyncStatusCode status = (*tracker_ptr)->Initialize(file_system_context); 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status != SYNC_STATUS_OK) 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Get all origins that have pending changes. 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::deque<FileSystemURL> urls; 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*tracker_ptr)->GetNextChangedURLs(&urls, 0); 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::deque<FileSystemURL>::iterator iter = urls.begin(); 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != urls.end(); ++iter) { 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) origins_with_changes->insert(iter->origin()); 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::DidInitializeChangeTrackerOnIOThread( 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<LocalFileChangeTracker>* tracker_ptr, 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& source_url, 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemContext* file_system_context, 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<GURL>* origins_with_changes, 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncStatusCode status) { 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(file_system_context); 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(origins_with_changes); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status != SYNC_STATUS_OK) { 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DidInitialize(source_url, file_system_context, status); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 536a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend* backend = 537a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend::GetBackend(file_system_context); 538a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(backend); 539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) backend->SetLocalFileChangeTracker(tracker_ptr->Pass()); 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) origins_with_pending_changes_.insert(origins_with_changes->begin(), 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) origins_with_changes->end()); 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScheduleNotifyChangesUpdatedOnIOThread(); 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) InitializeFileSystemContextOnIOThread(source_url, file_system_context); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::DidInitialize( 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& source_url, 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemContext* file_system_context, 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncStatusCode status) { 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ui_task_runner_->RunsTasksOnCurrentThread()) { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_task_runner_->PostTask( 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::DidInitialize, 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, source_url, 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_scoped_refptr(file_system_context), status)); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!ContainsKey(file_system_contexts_, file_system_context)); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ContainsKey(pending_initialize_callbacks_, file_system_context)); 563a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 564a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend* backend = 565a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend::GetBackend(file_system_context); 566a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(backend); 567a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(backend->change_tracker()); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_system_contexts_.insert(file_system_context); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StatusCallbackQueue& callback_queue = 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_initialize_callbacks_[file_system_context]; 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (StatusCallbackQueue::iterator iter = callback_queue.begin(); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != callback_queue.end(); ++iter) { 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_task_runner_->PostTask(FROM_HERE, base::Bind(*iter, status)); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_initialize_callbacks_.erase(file_system_context); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::GetNextURLsForSyncOnFileThread( 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemContext* file_system_context, 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::deque<FileSystemURL>* urls) { 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(file_system_context); 584a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(file_system_context->default_file_task_runner()-> 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunsTasksOnCurrentThread()); 586a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend* backend = 587a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend::GetBackend(file_system_context); 588a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(backend); 589a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(backend->change_tracker()); 590a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) backend->change_tracker()->GetNextChangedURLs( 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls, kMaxURLsToFetchForLocalSync); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::TryPrepareForLocalSync( 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemContext* file_system_context, 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::deque<FileSystemURL>* urls, 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LocalFileSyncInfoCallback& callback) { 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(urls); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (shutdown_on_ui_) { 602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(SYNC_STATUS_ABORT, LocalFileSyncInfo()); 603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (urls->empty()) { 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(SYNC_STATUS_NO_CHANGE_TO_SYNC, 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LocalFileSyncInfo()); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileSystemURL url = urls->front(); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls->pop_front(); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::deque<FileSystemURL>* remaining = new std::deque<FileSystemURL>; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remaining->swap(*urls); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrepareForSync( 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_system_context, url, 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::DidTryPrepareForLocalSync, 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, make_scoped_refptr(file_system_context), 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Owned(remaining), callback)); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::DidTryPrepareForLocalSync( 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemContext* file_system_context, 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::deque<FileSystemURL>* remaining_urls, 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LocalFileSyncInfoCallback& callback, 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncStatusCode status, 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LocalFileSyncInfo& sync_file_info) { 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status != SYNC_STATUS_FILE_BUSY) { 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(status, sync_file_info); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Recursively call TryPrepareForLocalSync with remaining_urls. 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TryPrepareForLocalSync(file_system_context, remaining_urls, callback); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::DidGetWritingStatusForSync( 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemContext* file_system_context, 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncStatusCode status, 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileSystemURL& url, 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LocalFileSyncInfoCallback& callback) { 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This gets called on UI thread and relays the task on FILE thread. 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(file_system_context); 646a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!file_system_context->default_file_task_runner()-> 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunsTasksOnCurrentThread()) { 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shutdown_on_ui_) { 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(SYNC_STATUS_ABORT, LocalFileSyncInfo()); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 653a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) file_system_context->default_file_task_runner()->PostTask( 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LocalFileSyncContext::DidGetWritingStatusForSync, 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, make_scoped_refptr(file_system_context), 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status, url, callback)); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 661a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend* backend = 662a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SyncFileSystemBackend::GetBackend(file_system_context); 663a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(backend); 664a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(backend->change_tracker()); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileChangeList changes; 666a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) backend->change_tracker()->GetChangesForURL(url, &changes); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath platform_path; 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::PlatformFileInfo file_info; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemFileUtil* file_util = file_system_context->GetFileUtil(url.type()); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(file_util); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::PlatformFileError file_error = file_util->GetFileInfo( 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_scoped_ptr( 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new FileSystemOperationContext(file_system_context)).get(), 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url, 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &file_info, 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &platform_path); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status == SYNC_STATUS_OK && 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_error != base::PLATFORM_FILE_OK && 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_error != base::PLATFORM_FILE_ERROR_NOT_FOUND) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status = PlatformFileErrorToSyncStatusCode(file_error); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!file_info.is_symbolic_link); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncFileType file_type = SYNC_FILE_TYPE_FILE; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_error == base::PLATFORM_FILE_ERROR_NOT_FOUND) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type = SYNC_FILE_TYPE_UNKNOWN; 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (file_info.is_directory) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_type = SYNC_FILE_TYPE_DIRECTORY; 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LocalFileSyncInfo sync_file_info; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_file_info.url = url; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_file_info.local_file_path = platform_path; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_file_info.metadata.file_type = file_type; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_file_info.metadata.size = file_info.size; 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_file_info.metadata.last_modified = file_info.last_modified; 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_file_info.changes = changes; 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_task_runner_->PostTask(FROM_HERE, 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(callback, status, sync_file_info)); 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::EnableWritingOnIOThread( 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileSystemURL& url) { 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!sync_status()) { 707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The service might have been shut down. 708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_status()->EndSyncing(url); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since a sync has finished the number of changes must have been updated. 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) origins_with_pending_changes_.insert(url.origin()); 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScheduleNotifyChangesUpdatedOnIOThread(); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::DidApplyRemoteChange( 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SyncStatusCallback& callback_on_ui, 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::PlatformFileError file_error) { 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_task_runner_->PostTask( 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(callback_on_ui, 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformFileErrorToSyncStatusCode(file_error))); 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnableWritingOnIOThread(url); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LocalFileSyncContext::DidGetFileMetadata( 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SyncFileMetadataCallback& callback, 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::PlatformFileError file_error, 7317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const base::PlatformFileInfo& file_info) { 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncFileMetadata metadata; 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_error == base::PLATFORM_FILE_OK) { 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) metadata.file_type = file_info.is_directory ? 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_FILE_TYPE_DIRECTORY : SYNC_FILE_TYPE_FILE; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) metadata.size = file_info.size; 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) metadata.last_modified = file_info.last_modified; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_task_runner_->PostTask( 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(callback, 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformFileErrorToSyncStatusCode(file_error), 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) metadata)); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta LocalFileSyncContext::NotifyChangesDuration() { 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mock_notify_changes_duration_in_sec_ >= 0) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::TimeDelta::FromSeconds(mock_notify_changes_duration_in_sec_); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::TimeDelta::FromSeconds(kNotifyChangesDurationInSec); 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void LocalFileSyncContext::DidCreateDirectoryForCopyIn( 754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileSystemContext* file_system_context, 755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& local_path, 756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const FileSystemURL& dest_url, 757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const StatusCallback& callback, 758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformFileError error) { 759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (error != base::PLATFORM_FILE_OK) { 760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(error); 761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 764868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FileSystemURL url_for_sync = CreateSyncableFileSystemURLForSync( 765868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context, dest_url); 766868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context->operation_runner()->CopyInForeignFile( 767868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) local_path, url_for_sync, callback); 768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace sync_file_system 771