sync_file_system_service.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/sync_file_system/extension_sync_event_observer.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_dependency_manager.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_file_sync_service.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync_file_system/local_file_sync_service.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync_file_system/sync_event_observer.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_notification_types.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_details.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_service.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "webkit/fileapi/file_system_context.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "webkit/fileapi/syncable/sync_direction.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "webkit/fileapi/syncable/sync_file_metadata.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "webkit/fileapi/syncable/sync_status_code.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using fileapi::FileSystemURL; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemURLSet; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sync_file_system { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SyncEventObserver::SyncServiceState RemoteStateToSyncServiceState( 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoteServiceState state) { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (state) { 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case REMOTE_SERVICE_OK: 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SyncEventObserver::SYNC_SERVICE_RUNNING; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case REMOTE_SERVICE_TEMPORARY_UNAVAILABLE: 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SyncEventObserver::SYNC_SERVICE_TEMPORARY_UNAVAILABLE; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case REMOTE_SERVICE_AUTHENTICATION_REQUIRED: 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SyncEventObserver::SYNC_SERVICE_AUTHENTICATION_REQUIRED; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case REMOTE_SERVICE_DISABLED: 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SyncEventObserver::SYNC_SERVICE_DISABLED; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SyncEventObserver::SYNC_SERVICE_DISABLED; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DidHandleOriginForExtensionUnloadedEvent( 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int type, 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_misc::UnloadedExtensionReason reason, 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& origin, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode code) { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(chrome::NOTIFICATION_EXTENSION_UNLOADED == type); 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(extension_misc::UNLOAD_REASON_DISABLE == reason || 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_misc::UNLOAD_REASON_UNINSTALL == reason); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (code != SYNC_STATUS_OK) { 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (reason) { 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case extension_misc::UNLOAD_REASON_DISABLE: 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "Disabling origin for UNLOAD(DISABLE) failed: " 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << origin.spec(); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case extension_misc::UNLOAD_REASON_UNINSTALL: 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "Uninstall origin for UNLOAD(UNINSTALL) failed: " 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << origin.spec(); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DidHandleOriginForExtensionEnabledEvent( 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int type, 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& origin, 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode code) { 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(chrome::NOTIFICATION_EXTENSION_ENABLED == type); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (code != SYNC_STATUS_OK) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "Enabling origin for ENABLED failed: " << origin.spec(); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemService::Shutdown() { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_file_service_->Shutdown(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_file_service_.reset(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remote_file_service_.reset(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileSyncServiceBase* profile_sync_service = 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileSyncServiceFactory::GetForProfile(profile_); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (profile_sync_service) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_sync_service->RemoveObserver(this); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_ = NULL; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncFileSystemService::~SyncFileSystemService() { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!profile_); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemService::InitializeForApp( 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fileapi::FileSystemContext* file_system_context, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& service_name, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& app_origin, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SyncStatusCallback& callback) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(local_file_service_); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(remote_file_service_); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(app_origin == app_origin.GetOrigin()); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "InitializeForApp: " << app_origin.spec(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_file_service_->MaybeInitializeFileSystemContext( 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_origin, service_name, file_system_context, 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SyncFileSystemService::DidInitializeFileSystem, 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr(), app_origin, callback)); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::GetFileSyncStatus( 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, const SyncFileStatusCallback& callback) { 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(local_file_service_); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(remote_file_service_); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It's possible to get an invalid FileEntry. 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!url.is_valid()) { 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_FILE_ERROR_INVALID_URL, 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_FILE_STATUS_UNKNOWN)); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (remote_file_service_->IsConflicting(url)) { 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_STATUS_OK, 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_FILE_STATUS_CONFLICTING)); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->HasPendingLocalChanges( 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url, 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SyncFileSystemService::DidGetLocalChangeStatus, 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr(), callback)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::AddSyncEventObserver(SyncEventObserver* observer) { 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observers_.AddObserver(observer); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::RemoveSyncEventObserver( 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncEventObserver* observer) { 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) observers_.RemoveObserver(observer); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ConflictResolutionPolicy 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SyncFileSystemService::GetConflictResolutionPolicy() const { 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return remote_file_service_->GetConflictResolutionPolicy(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SyncStatusCode SyncFileSystemService::SetConflictResolutionPolicy( 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConflictResolutionPolicy policy) { 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return remote_file_service_->SetConflictResolutionPolicy(policy); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncFileSystemService::SyncFileSystemService(Profile* profile) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : profile_(profile), 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_local_changes_(0), 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_remote_changes_(0), 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_sync_running_(false), 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_sync_running_(false), 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_waiting_remote_sync_enabled_(false), 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sync_enabled_(true) { 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemService::Initialize( 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<LocalFileSyncService> local_file_service, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RemoteFileSyncService> remote_file_service) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(local_file_service); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(remote_file_service); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(profile_); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_file_service_ = local_file_service.Pass(); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remote_file_service_ = remote_file_service.Pass(); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->AddChangeObserver(this); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->SetLocalChangeProcessor( 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->GetLocalChangeProcessor()); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->AddServiceObserver(this); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->AddFileStatusObserver(this); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->SetRemoteChangeProcessor(local_file_service_.get()); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileSyncServiceBase* profile_sync_service = 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileSyncServiceFactory::GetForProfile(profile_); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (profile_sync_service) { 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateSyncEnabledStatus(profile_sync_service); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_sync_service->AddObserver(this); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<Profile>(profile_)); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_ENABLED, 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<Profile>(profile_)); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidInitializeFileSystem( 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& app_origin, 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SyncStatusCallback& callback, 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode status) { 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "DidInitializeFileSystem: " 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << app_origin.spec() << " " << status; 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status != SYNC_STATUS_OK) { 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(status); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Local side of initialization for the app is done. 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Continue on initializing the remote side. 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->RegisterOriginForTrackingChanges( 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_origin, 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SyncFileSystemService::DidRegisterOrigin, 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr(), app_origin, callback)); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidRegisterOrigin( 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& app_origin, 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SyncStatusCallback& callback, 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode status) { 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "DidRegisterOrigin: " << app_origin.spec() << " " << status; 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(status); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::SetSyncEnabledForTesting(bool enabled) { 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sync_enabled_ = enabled; 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->SetSyncEnabled(sync_enabled_); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::MaybeStartSync() { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!profile_ || !sync_enabled_) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(local_file_service_); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(remote_file_service_); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MaybeStartRemoteSync(); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MaybeStartLocalSync(); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::MaybeStartRemoteSync() { 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (remote_file_service_->GetCurrentState() == REMOTE_SERVICE_DISABLED) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // See if we cannot / should not start a new remote sync. 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (remote_sync_running_ || pending_remote_changes_ == 0) 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we have registered a URL for waiting until sync is enabled on a 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // file (and the registerred URL seems to be still valid) it won't be 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // worth trying to start another remote sync. 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_waiting_remote_sync_enabled_) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(sync_enabled_); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Calling ProcessRemoteChange"; 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_sync_running_ = true; 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->ProcessRemoteChange( 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SyncFileSystemService::DidProcessRemoteChange, 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr())); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::MaybeStartLocalSync() { 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the remote service is not ready probably we should not start a 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // local sync yet. 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (We should be still trying a remote sync so the state should become OK 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // if the remote-side attempt succeeds.) 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (remote_file_service_->GetCurrentState() != REMOTE_SERVICE_OK) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // See if we cannot / should not start a new local sync. 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (local_sync_running_ || pending_local_changes_ == 0) 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Calling ProcessLocalChange"; 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_sync_running_ = true; 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->ProcessLocalChange( 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SyncFileSystemService::DidProcessLocalChange, 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr())); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidProcessRemoteChange( 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode status, 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url) { 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "DidProcessRemoteChange: " 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " status=" << status 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " (" << SyncStatusCodeToString(status) << ")" 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " url=" << url.DebugString(); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(remote_sync_running_); 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_sync_running_ = false; 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status != SYNC_STATUS_NO_CHANGE_TO_SYNC && 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->GetCurrentState() != REMOTE_SERVICE_DISABLED) { 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(url.is_valid()); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->ClearSyncFlagForURL(url); 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status == SYNC_STATUS_NO_CHANGE_TO_SYNC) { 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We seem to have no changes to work on for now. 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(kinuko): Might be better setting a timer to call MaybeStartSync. 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status == SYNC_STATUS_FILE_BUSY) { 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_waiting_remote_sync_enabled_ = true; 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->RegisterURLForWaitingSync( 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url, base::Bind(&SyncFileSystemService::OnSyncEnabledForRemoteSync, 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr())); 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(&SyncFileSystemService::MaybeStartSync, 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr())); 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidProcessLocalChange( 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode status, const FileSystemURL& url) { 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "DidProcessLocalChange:" 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " status=" << status 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " (" << SyncStatusCodeToString(status) << ")" 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " url=" << url.DebugString(); 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(local_sync_running_); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_sync_running_ = false; 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status == SYNC_STATUS_NO_CHANGE_TO_SYNC) { 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We seem to have no changes to work on for now. 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(url.is_valid()); 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->ClearSyncFlagForURL(url); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(&SyncFileSystemService::MaybeStartSync, 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr())); 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidGetLocalChangeStatus( 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SyncFileStatusCallback& callback, 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncStatusCode status, 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_pending_local_changes) { 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run( 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status, 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_pending_local_changes ? 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SYNC_FILE_STATUS_HAS_PENDING_CHANGES : SYNC_FILE_STATUS_SYNCED); 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnSyncEnabledForRemoteSync() { 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_waiting_remote_sync_enabled_ = false; 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MaybeStartRemoteSync(); 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnLocalChangeAvailable(int64 pending_changes) { 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(pending_changes, 0); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "OnLocalChangeAvailable: " << pending_changes; 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_local_changes_ = pending_changes; 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(&SyncFileSystemService::MaybeStartSync, 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr())); 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnRemoteChangeQueueUpdated(int64 pending_changes) { 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(pending_changes, 0); 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "OnRemoteChangeQueueUpdated: " << pending_changes; 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_remote_changes_ = pending_changes; 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (pending_changes > 0) { 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The smallest change available might have changed from the previous one. 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Reset the is_waiting_remote_sync_enabled_ flag so that we can retry. 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_waiting_remote_sync_enabled_ = false; 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(&SyncFileSystemService::MaybeStartSync, 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr())); 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnRemoteServiceStateUpdated( 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoteServiceState state, 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& description) { 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "OnRemoteServiceStateUpdated: " << state 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " " << description; 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (state == REMOTE_SERVICE_OK) { 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(&SyncFileSystemService::MaybeStartSync, 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr())); 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER( 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncEventObserver, observers_, 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnSyncStateUpdated(GURL(), 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoteStateToSyncServiceState(state), 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) description)); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::Observe( 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int type, 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationSource& source, 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationDetails& details) { 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Delivered when an app is disabled, reloaded or restarted. 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_UNLOADED: 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HandleExtensionUnloaded(type, details); 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Delivered when an app is enabled, reloaded or restarted. 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_ENABLED: 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HandleExtensionEnabled(type, details); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED() << "Unknown notification."; 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::HandleExtensionUnloaded( 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int type, 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationDetails& details) { 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Details<const extensions::UnloadedExtensionInfo> info = 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Details<const extensions::UnloadedExtensionInfo>(details); 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string extension_id = info->extension->id(); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL app_origin = 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::Extension::GetBaseURLFromExtensionId(extension_id); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (info->reason) { 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case extension_misc::UNLOAD_REASON_DISABLE: 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Handle extension notification for UNLOAD(DISABLE): " 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << app_origin; 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->DisableOriginForTrackingChanges( 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_origin, 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DidHandleOriginForExtensionUnloadedEvent, 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type, info->reason, app_origin)); 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->SetOriginEnabled(app_origin, false); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case extension_misc::UNLOAD_REASON_UNINSTALL: 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Handle extension notification for UNLOAD(UNINSTALL): " 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << app_origin; 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->UninstallOrigin( 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_origin, 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DidHandleOriginForExtensionUnloadedEvent, 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type, info->reason, app_origin)); 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->SetOriginEnabled(app_origin, false); 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Nothing to do. 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::HandleExtensionEnabled( 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int type, 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationDetails& details) { 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string extension_id = 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Details<const extensions::Extension>(details)->id(); 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL app_origin = 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::Extension::GetBaseURLFromExtensionId(extension_id); 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Handle extension notification for ENABLED: " << app_origin; 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->EnableOriginForTrackingChanges( 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) app_origin, 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&DidHandleOriginForExtensionEnabledEvent, type, app_origin)); 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) local_file_service_->SetOriginEnabled(app_origin, true); 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnStateChanged() { 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileSyncServiceBase* profile_sync_service = 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileSyncServiceFactory::GetForProfile(profile_); 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (profile_sync_service) 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateSyncEnabledStatus(profile_sync_service); 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnFileStatusChanged( 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& url, 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncFileStatus sync_status, 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncAction action_taken, 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncDirection direction) { 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER( 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncEventObserver, observers_, 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnFileSynced(url, sync_status, action_taken, direction)); 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::UpdateSyncEnabledStatus( 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProfileSyncServiceBase* profile_sync_service) { 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!profile_sync_service->HasSyncSetupCompleted()) 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sync_enabled_ = profile_sync_service->GetPreferredDataTypes().Has( 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::APPS); 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remote_file_service_->SetSyncEnabled(sync_enabled_); 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sync_enabled_) { 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(&SyncFileSystemService::MaybeStartSync, 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AsWeakPtr())); 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sync_file_system 515