sync_file_system_service.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync_file_system/sync_file_system_service.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/format_macros.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h" 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/sync_file_system/extension_sync_event_observer.h" 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/extensions/api/sync_file_system/sync_file_system_api_helpers.h" 17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/extensions/extension_prefs.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h" 2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend_v1/drive_file_sync_service.h" 222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/local/local_file_sync_service.h" 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/sync_file_system/logger.h" 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/sync_file_system/sync_direction.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync_file_system/sync_event_observer.h" 262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_file_metadata.h" 272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/sync_status_code.h" 282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/sync_file_system/syncable_file_system_util.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension.h" 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "components/browser_context_keyed_service/browser_context_dependency_manager.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_details.h" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_service.h" 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/browser/storage_partition.h" 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "extensions/common/manifest_constants.h" 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_context.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using extensions::Extension; 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using extensions::ExtensionPrefs; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using fileapi::FileSystemURL; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemURLSet; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sync_file_system { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Default delay when more changes are available. 5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int64 kSyncDelayInMilliseconds = 1 * base::Time::kMillisecondsPerSecond; 5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Default delay when there're more than 10 pending changes. 5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int64 kSyncDelayFastInMilliseconds = 100; 5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kPendingChangeThresholdForFastSync = 10; 5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Default delay when remote service is temporarily unavailable. 5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int64 kSyncDelaySlowInMilliseconds = 5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 30 * base::Time::kMillisecondsPerSecond; // Start with 30 sec + exp backoff 5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Default delay when there're no changes. 6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int64 kSyncDelayMaxInMilliseconds = 6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 30 * 60 * base::Time::kMillisecondsPerSecond; // 30 min 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SyncServiceState RemoteStateToSyncServiceState( 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoteServiceState state) { 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (state) { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case REMOTE_SERVICE_OK: 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SYNC_SERVICE_RUNNING; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case REMOTE_SERVICE_TEMPORARY_UNAVAILABLE: 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SYNC_SERVICE_TEMPORARY_UNAVAILABLE; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case REMOTE_SERVICE_AUTHENTICATION_REQUIRED: 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SYNC_SERVICE_AUTHENTICATION_REQUIRED; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case REMOTE_SERVICE_DISABLED: 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SYNC_SERVICE_DISABLED; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NOTREACHED() << "Unknown remote service state: " << state; 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SYNC_SERVICE_DISABLED; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DidHandleOriginForExtensionUnloadedEvent( 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int type, 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& origin, 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode code) { 84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(chrome::NOTIFICATION_EXTENSION_UNLOADED == type || 85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_UNINSTALLED == type); 86b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (code != SYNC_STATUS_OK && 87b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) code != SYNC_STATUS_UNKNOWN_ORIGIN) { 88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) switch (type) { 89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_UNLOADED: 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) util::Log(logging::LOG_WARNING, 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "Disabling origin for UNLOADED(DISABLE) failed: %s", 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) origin.spec().c_str()); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) util::Log(logging::LOG_WARNING, 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "Uninstall origin for UNINSTALLED failed: %s", 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) origin.spec().c_str()); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DidHandleOriginForExtensionEnabledEvent( 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int type, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& origin, 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode code) { 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(chrome::NOTIFICATION_EXTENSION_ENABLED == type); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (code != SYNC_STATUS_OK) 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) util::Log(logging::LOG_WARNING, 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "Enabling origin for ENABLED failed: %s", 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) origin.spec().c_str()); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string SyncFileStatusToString(SyncFileStatus sync_file_status) { 1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return extensions::api::sync_file_system::ToString( 1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch extensions::SyncFileStatusToExtensionEnum(sync_file_status)); 1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Gets called repeatedly until every SyncFileStatus has been mapped. 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DidGetFileSyncStatusForDump( 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::ListValue* files, 1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) size_t* num_results, 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const SyncFileSystemService::DumpFilesCallback& callback, 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::DictionaryValue* file, 1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SyncStatusCode sync_status_code, 1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SyncFileStatus sync_file_status) { 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(files); 1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(num_results); 1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (file) 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch file->SetString("status", SyncFileStatusToString(sync_file_status)); 1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Once all results have been received, run the callback to signal end. 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK_LE(*num_results, files->GetSize()); 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (++*num_results < files->GetSize()) 1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch callback.Run(files); 1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class SyncFileSystemService::SyncRunner { 149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public: 150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) typedef base::Callback<void(const SyncStatusCallback&)> Task; 151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SyncRunner(const std::string& task_name, 152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const Task& sync_task, 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RemoteFileSyncService* remote_service) 154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : task_name_(task_name), 155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sync_task_(sync_task), 156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) remote_service_(remote_service), 157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) current_delay_(0), 158d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) last_delay_(0), 159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pending_changes_(0), 160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) running_(false), 161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) factory_(this) {} 162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ~SyncRunner() {} 163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void Schedule() { 16568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int64 delay = kSyncDelayInMilliseconds; 166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (pending_changes_ == 0) { 16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScheduleInternal(kSyncDelayMaxInMilliseconds); 168d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) switch (remote_service_->GetCurrentState()) { 171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case REMOTE_SERVICE_OK: 17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (pending_changes_ > kPendingChangeThresholdForFastSync) 17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) delay = kSyncDelayFastInMilliseconds; 17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) else 17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) delay = kSyncDelayInMilliseconds; 176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) break; 177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 178d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case REMOTE_SERVICE_TEMPORARY_UNAVAILABLE: 17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) delay = kSyncDelaySlowInMilliseconds; 18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (last_delay_ >= kSyncDelaySlowInMilliseconds && 18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) last_delay_ < kSyncDelayMaxInMilliseconds) 182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) delay = last_delay_ * 2; 183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) break; 184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 185d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case REMOTE_SERVICE_AUTHENTICATION_REQUIRED: 186d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case REMOTE_SERVICE_DISABLED: 18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) delay = kSyncDelayMaxInMilliseconds; 188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) break; 189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ScheduleInternal(delay); 191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void ScheduleIfNotRunning() { 194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!timer_.IsRunning()) 195d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Schedule(); 196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 198d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void OnChangesUpdated(int64 pending_changes) { 199d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_GE(pending_changes, 0); 200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (pending_changes_ != pending_changes) { 201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) util::Log(logging::LOG_VERBOSE, FROM_HERE, 202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "[%s] pending_changes updated: %" PRId64, 203d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) task_name_.c_str(), pending_changes); 204d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) pending_changes_ = pending_changes; 206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Schedule(); 207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 209d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int64 pending_changes() const { return pending_changes_; } 210d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private: 212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void Finished(SyncStatusCode status) { 213d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(running_); 214d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) running_ = false; 215d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) util::Log(logging::LOG_VERBOSE, FROM_HERE, 216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "[%s] * Finished (elapsed: %" PRId64 " sec)", 217d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) task_name_.c_str(), 218d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) (base::Time::Now() - last_scheduled_).InSeconds()); 219d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (status == SYNC_STATUS_NO_CHANGE_TO_SYNC || 220d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) status == SYNC_STATUS_FILE_BUSY) 22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScheduleInternal(kSyncDelayMaxInMilliseconds); 222d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) else 223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Schedule(); 224d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void Run() { 227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (running_) 228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) running_ = true; 230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) last_scheduled_ = base::Time::Now(); 231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) last_delay_ = current_delay_; 232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) util::Log(logging::LOG_VERBOSE, FROM_HERE, 234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "[%s] * Started", task_name_.c_str()); 235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sync_task_.Run(base::Bind(&SyncRunner::Finished, factory_.GetWeakPtr())); 237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void ScheduleInternal(int64 delay) { 24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::TimeDelta time_to_next = base::TimeDelta::FromMilliseconds(delay); 241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (timer_.IsRunning()) { 243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (current_delay_ == delay) 244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::TimeDelta elapsed = base::Time::Now() - last_scheduled_; 24768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (elapsed < time_to_next) { 248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) time_to_next = time_to_next - elapsed; 24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 25068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) time_to_next = base::TimeDelta::FromMilliseconds( 25168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) kSyncDelayFastInMilliseconds); 25268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) timer_.Stop(); 254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (current_delay_ != delay) { 257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) util::Log(logging::LOG_VERBOSE, FROM_HERE, 258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "[%s] Scheduling task in %" PRId64 " secs", 259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) task_name_.c_str(), time_to_next.InSeconds()); 260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) current_delay_ = delay; 262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) timer_.Start(FROM_HERE, time_to_next, this, &SyncRunner::Run); 264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::string task_name_; 267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Task sync_task_; 268d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RemoteFileSyncService* remote_service_; 269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::OneShotTimer<SyncRunner> timer_; 270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Time last_scheduled_; 271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int64 current_delay_; 272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int64 last_delay_; 273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int64 pending_changes_; 274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool running_; 275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::WeakPtrFactory<SyncRunner> factory_; 276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SyncRunner); 278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}; 279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)//----------------------------------------------------------------------------- 281d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemService::Shutdown() { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) local_sync_.reset(); 286d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) remote_sync_.reset(); 287d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_file_service_->Shutdown(); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_file_service_.reset(); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remote_file_service_.reset(); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileSyncServiceBase* profile_sync_service = 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileSyncServiceFactory::GetForProfile(profile_); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (profile_sync_service) 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_sync_service->RemoveObserver(this); 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_ = NULL; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncFileSystemService::~SyncFileSystemService() { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!profile_); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemService::InitializeForApp( 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fileapi::FileSystemContext* file_system_context, 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& app_origin, 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SyncStatusCallback& callback) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(local_file_service_); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(remote_file_service_); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(app_origin == app_origin.GetOrigin()); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) util::Log(logging::LOG_VERBOSE, FROM_HERE, 3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "Initializing for App: %s", app_origin.spec().c_str()); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_file_service_->MaybeInitializeFileSystemContext( 318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) app_origin, file_system_context, 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SyncFileSystemService::DidInitializeFileSystem, 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr(), app_origin, callback)); 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SyncServiceState SyncFileSystemService::GetSyncServiceState() { 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return RemoteStateToSyncServiceState(remote_file_service_->GetCurrentState()); 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void SyncFileSystemService::GetExtensionStatusMap( 328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::map<GURL, std::string>* status_map) { 329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(status_map); 330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) remote_file_service_->GetOriginStatusMap(status_map); 331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SyncFileSystemService::DumpFiles(const GURL& origin, 3347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const DumpFilesCallback& callback) { 335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!origin.is_empty()); 3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch content::StoragePartition* storage_partition = 3387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch content::BrowserContext::GetStoragePartitionForSite(profile_, origin); 3397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch fileapi::FileSystemContext* file_system_context = 3407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch storage_partition->GetFileSystemContext(); 3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch local_file_service_->MaybeInitializeFileSystemContext( 3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch origin, file_system_context, 3437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&SyncFileSystemService::DidInitializeFileSystemForDump, 3447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AsWeakPtr(), origin, callback)); 3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::GetFileSyncStatus( 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, const SyncFileStatusCallback& callback) { 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(local_file_service_); 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(remote_file_service_); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It's possible to get an invalid FileEntry. 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!url.is_valid()) { 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_FILE_ERROR_INVALID_URL, 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_FILE_STATUS_UNKNOWN)); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (remote_file_service_->IsConflicting(url)) { 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_STATUS_OK, 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_FILE_STATUS_CONFLICTING)); 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->HasPendingLocalChanges( 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url, 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SyncFileSystemService::DidGetLocalChangeStatus, 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr(), callback)); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::AddSyncEventObserver(SyncEventObserver* observer) { 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observers_.AddObserver(observer); 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::RemoveSyncEventObserver( 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncEventObserver* observer) { 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observers_.RemoveObserver(observer); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ConflictResolutionPolicy 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SyncFileSystemService::GetConflictResolutionPolicy() const { 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return remote_file_service_->GetConflictResolutionPolicy(); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SyncStatusCode SyncFileSystemService::SetConflictResolutionPolicy( 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConflictResolutionPolicy policy) { 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return remote_file_service_->SetConflictResolutionPolicy(policy); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncFileSystemService::SyncFileSystemService(Profile* profile) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : profile_(profile), 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sync_enabled_(true) { 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemService::Initialize( 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<LocalFileSyncService> local_file_service, 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RemoteFileSyncService> remote_file_service) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(local_file_service); 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(remote_file_service); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(profile_); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_file_service_ = local_file_service.Pass(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remote_file_service_ = remote_file_service.Pass(); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->AddChangeObserver(this); 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->SetLocalChangeProcessor( 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->GetLocalChangeProcessor()); 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->AddServiceObserver(this); 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->AddFileStatusObserver(this); 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->SetRemoteChangeProcessor(local_file_service_.get()); 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 420d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) local_sync_.reset(new SyncRunner( 421d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "Local sync", 422d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&SyncFileSystemService::StartLocalSync, AsWeakPtr()), 423d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) remote_file_service_.get())); 424d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) remote_sync_.reset(new SyncRunner( 425d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "Remote sync", 426d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&SyncFileSystemService::StartRemoteSync, AsWeakPtr()), 427d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) remote_file_service_.get())); 428d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileSyncServiceBase* profile_sync_service = 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileSyncServiceFactory::GetForProfile(profile_); 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (profile_sync_service) { 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateSyncEnabledStatus(profile_sync_service); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_sync_service->AddObserver(this); 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::Source<Profile>(profile_)); 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<Profile>(profile_)); 440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED, 441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::Source<Profile>(profile_)); 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_ENABLED, 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<Profile>(profile_)); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidInitializeFileSystem( 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& app_origin, 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SyncStatusCallback& callback, 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode status) { 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "DidInitializeFileSystem: " 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << app_origin.spec() << " " << status; 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status != SYNC_STATUS_OK) { 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(status); 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Local side of initialization for the app is done. 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Continue on initializing the remote side. 46058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) remote_file_service_->RegisterOrigin( 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_origin, 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SyncFileSystemService::DidRegisterOrigin, 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr(), app_origin, callback)); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidRegisterOrigin( 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& app_origin, 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SyncStatusCallback& callback, 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode status) { 47058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) util::Log(logging::LOG_VERBOSE, FROM_HERE, 47158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "DidInitializeForApp (registered the origin): %s: %s", 47258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) app_origin.spec().c_str(), 47358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SyncStatusCodeToString(status)); 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(status); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SyncFileSystemService::DidInitializeFileSystemForDump( 4797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const GURL& origin, 4807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const DumpFilesCallback& callback, 4817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SyncStatusCode status) { 4827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!origin.is_empty()); 4837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (status != SYNC_STATUS_OK) { 4857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::ListValue empty_result; 4867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch callback.Run(&empty_result); 4877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 4887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 4897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::ListValue* files = remote_file_service_->DumpFiles(origin).release(); 4917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!files->GetSize()) { 4927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch callback.Run(files); 4937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 4947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 4957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Callback<void(base::DictionaryValue* file, 4977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SyncStatusCode sync_status, 4987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SyncFileStatus sync_file_status)> completion_callback = 4997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&DidGetFileSyncStatusForDump, base::Owned(files), 5007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Owned(new size_t(0)), callback); 5017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // After all metadata loaded, sync status can be added to each entry. 5037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (size_t i = 0; i < files->GetSize(); ++i) { 5047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::DictionaryValue* file = NULL; 5057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string path_string; 5067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!files->GetDictionary(i, &file) || 5077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch !file->GetString("path", &path_string)) { 5087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NOTREACHED(); 5097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch completion_callback.Run( 5107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NULL, SYNC_FILE_ERROR_FAILED, SYNC_FILE_STATUS_UNKNOWN); 5117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch continue; 5127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 5137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::FilePath file_path = base::FilePath::FromUTF8Unsafe(path_string); 5157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FileSystemURL url = CreateSyncableFileSystemURL(origin, file_path); 5167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetFileSyncStatus(url, base::Bind(completion_callback, file)); 5177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 5187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 5197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::SetSyncEnabledForTesting(bool enabled) { 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sync_enabled_ = enabled; 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->SetSyncEnabled(sync_enabled_); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void SyncFileSystemService::StartLocalSync( 526d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const SyncStatusCallback& callback) { 527d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) local_file_service_->ProcessLocalChange( 528d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&SyncFileSystemService::DidProcessLocalChange, AsWeakPtr(), 529d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) callback)); 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 532d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void SyncFileSystemService::StartRemoteSync( 533d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const SyncStatusCallback& callback) { 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->ProcessRemoteChange( 535d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&SyncFileSystemService::DidProcessRemoteChange, AsWeakPtr(), 536d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) callback)); 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidProcessRemoteChange( 540d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const SyncStatusCallback& callback, 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode status, 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url) { 5437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) util::Log(logging::LOG_VERBOSE, FROM_HERE, 5447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "ProcessRemoteChange finished with status=%d (%s) for url=%s", 5457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) status, SyncStatusCodeToString(status), url.DebugString().c_str()); 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 547d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (url.is_valid()) 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->ClearSyncFlagForURL(url); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status == SYNC_STATUS_FILE_BUSY) { 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->RegisterURLForWaitingSync( 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url, base::Bind(&SyncFileSystemService::OnSyncEnabledForRemoteSync, 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr())); 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 556d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) callback.Run(status); 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidProcessLocalChange( 560d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const SyncStatusCallback& callback, 561d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SyncStatusCode status, 562d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemURL& url) { 5637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) util::Log(logging::LOG_VERBOSE, FROM_HERE, 5647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "ProcessLocalChange finished with status=%d (%s) for url=%s", 5657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) status, SyncStatusCodeToString(status), url.DebugString().c_str()); 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 567d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (url.is_valid()) 568d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) local_file_service_->ClearSyncFlagForURL(url); 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 570d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) callback.Run(status); 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidGetLocalChangeStatus( 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SyncFileStatusCallback& callback, 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode status, 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_pending_local_changes) { 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run( 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status, 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_pending_local_changes ? 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_FILE_STATUS_HAS_PENDING_CHANGES : SYNC_FILE_STATUS_SYNCED); 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnSyncEnabledForRemoteSync() { 584d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) remote_sync_->Schedule(); 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnLocalChangeAvailable(int64 pending_changes) { 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 590d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) local_sync_->OnChangesUpdated(pending_changes); 591d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) remote_sync_->ScheduleIfNotRunning(); 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnRemoteChangeQueueUpdated(int64 pending_changes) { 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 597d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) remote_sync_->OnChangesUpdated(pending_changes); 598d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) local_sync_->ScheduleIfNotRunning(); 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnRemoteServiceStateUpdated( 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoteServiceState state, 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& description) { 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) util::Log(logging::LOG_INFO, FROM_HERE, 6067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "OnRemoteServiceStateChanged: %d %s", state, description.c_str()); 607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 608d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) remote_sync_->Schedule(); 609d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) local_sync_->Schedule(); 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER( 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncEventObserver, observers_, 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnSyncStateUpdated(GURL(), 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoteStateToSyncServiceState(state), 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) description)); 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::Observe( 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int type, 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationSource& source, 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationDetails& details) { 622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Event notification sequence. 623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // (User action) (Notification type) 625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Install: INSTALLED. 626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Update: INSTALLED. 627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Uninstall: UNINSTALLED. 628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Launch, Close: No notification. 629868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Enable: ENABLED. 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Disable: UNLOADED(DISABLE). 631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Reload, Restart: UNLOADED(DISABLE) -> INSTALLED -> ENABLED. 632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_INSTALLED: 635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HandleExtensionInstalled(details); 636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_UNLOADED: 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HandleExtensionUnloaded(type, details); 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 640a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: 641a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) HandleExtensionUninstalled(type, details); 642a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) break; 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_ENABLED: 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HandleExtensionEnabled(type, details); 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED() << "Unknown notification."; 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SyncFileSystemService::HandleExtensionInstalled( 653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const content::NotificationDetails& details) { 654d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const Extension* extension = 655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::Details<const extensions::InstalledExtensionInfo>(details)-> 656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension; 657d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) GURL app_origin = Extension::GetBaseURLFromExtensionId(extension->id()); 658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "Handle extension notification for INSTALLED: " << app_origin; 659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // NOTE: When an app is uninstalled and re-installed in a sequence, 660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |local_file_service_| may still keeps |app_origin| as disabled origin. 661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) local_file_service_->SetOriginEnabled(app_origin, true); 662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::HandleExtensionUnloaded( 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int type, 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationDetails& details) { 667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::Details<const extensions::UnloadedExtensionInfo> info(details); 668a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (info->reason != extension_misc::UNLOAD_REASON_DISABLE) 669a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 670d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 671d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::string extension_id = info->extension->id(); 672d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) GURL app_origin = Extension::GetBaseURLFromExtensionId(extension_id); 673d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 674d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int reasons = ExtensionPrefs::Get(profile_)->GetDisableReasons(extension_id); 675d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (reasons & Extension::DISABLE_RELOAD) { 676d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Bypass disabling the origin since the app will be re-enabled soon. 677d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // NOTE: If re-enabling the app fails, the app is disabled while it is 678d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // handled as enabled origin in the SyncFS. This should be safe and will be 679d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // recovered when the user re-enables the app manually or the sync service 680d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // restarts. 681d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << "Handle extension notification for UNLOAD(DISABLE_RELOAD): " 682d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << app_origin; 683d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 684d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 685d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 686a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DVLOG(1) << "Handle extension notification for UNLOAD(DISABLE): " 687a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) << app_origin; 68858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) remote_file_service_->DisableOrigin( 689a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) app_origin, 690a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&DidHandleOriginForExtensionUnloadedEvent, 691a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) type, app_origin)); 692a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) local_file_service_->SetOriginEnabled(app_origin, false); 693a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 695a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void SyncFileSystemService::HandleExtensionUninstalled( 696a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int type, 697a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const content::NotificationDetails& details) { 69868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const Extension* extension = content::Details<const Extension>(details).ptr(); 69968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(extension); 70068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 70168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RemoteFileSyncService::UninstallFlag flag = 70268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RemoteFileSyncService::UNINSTALL_AND_PURGE_REMOTE; 70368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If it's loaded from an unpacked package and with key: field, 70468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // the uninstall will not be sync'ed and the user might be using the 70568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // same app key in other installs, so avoid purging the remote folder. 70668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (extensions::Manifest::IsUnpackedLocation(extension->location()) && 70768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) extension->manifest()->HasKey(extensions::manifest_keys::kKey)) { 70868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) flag = RemoteFileSyncService::UNINSTALL_AND_KEEP_REMOTE; 70968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 71068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 71168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GURL app_origin = Extension::GetBaseURLFromExtensionId(extension->id()); 712a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DVLOG(1) << "Handle extension notification for UNINSTALLED: " 713a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) << app_origin; 714a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) remote_file_service_->UninstallOrigin( 71568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) app_origin, flag, 716a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Bind(&DidHandleOriginForExtensionUnloadedEvent, 717a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) type, app_origin)); 718a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) local_file_service_->SetOriginEnabled(app_origin, false); 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::HandleExtensionEnabled( 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int type, 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationDetails& details) { 724d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::string extension_id = content::Details<const Extension>(details)->id(); 725d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) GURL app_origin = Extension::GetBaseURLFromExtensionId(extension_id); 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Handle extension notification for ENABLED: " << app_origin; 72758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) remote_file_service_->EnableOrigin( 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_origin, 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DidHandleOriginForExtensionEnabledEvent, type, app_origin)); 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->SetOriginEnabled(app_origin, true); 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnStateChanged() { 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileSyncServiceBase* profile_sync_service = 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileSyncServiceFactory::GetForProfile(profile_); 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (profile_sync_service) 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateSyncEnabledStatus(profile_sync_service); 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnFileStatusChanged( 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncFileStatus sync_status, 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncAction action_taken, 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncDirection direction) { 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER( 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncEventObserver, observers_, 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnFileSynced(url, sync_status, action_taken, direction)); 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::UpdateSyncEnabledStatus( 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileSyncServiceBase* profile_sync_service) { 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!profile_sync_service->HasSyncSetupCompleted()) 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 754d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool old_sync_enabled = sync_enabled_; 755868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sync_enabled_ = profile_sync_service->GetActiveDataTypes().Has( 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::APPS); 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->SetSyncEnabled(sync_enabled_); 758d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!old_sync_enabled && sync_enabled_) { 759d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) local_sync_->Schedule(); 760d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) remote_sync_->Schedule(); 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sync_file_system 765