sync_file_system_service.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync_file_system/local_file_sync_service.h"
1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/sync_file_system/logger.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"
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_details.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/notification_service.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_context.h"
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/syncable/sync_direction.h"
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/syncable/sync_file_metadata.h"
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/syncable/sync_status_code.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using fileapi::FileSystemURL;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemURLSet;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sync_file_system {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int64 kRetryTimerIntervalInSeconds = 20 * 60;  // 20 min.
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SyncServiceState RemoteStateToSyncServiceState(
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RemoteServiceState state) {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (state) {
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case REMOTE_SERVICE_OK:
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return SYNC_SERVICE_RUNNING;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case REMOTE_SERVICE_TEMPORARY_UNAVAILABLE:
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return SYNC_SERVICE_TEMPORARY_UNAVAILABLE;
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case REMOTE_SERVICE_AUTHENTICATION_REQUIRED:
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return SYNC_SERVICE_AUTHENTICATION_REQUIRED;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case REMOTE_SERVICE_DISABLED:
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return SYNC_SERVICE_DISABLED;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NOTREACHED() << "Unknown remote service state: " << state;
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return SYNC_SERVICE_DISABLED;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DidHandleOriginForExtensionUnloadedEvent(
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int type,
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    extension_misc::UnloadedExtensionReason reason,
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& origin,
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncStatusCode code) {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(chrome::NOTIFICATION_EXTENSION_UNLOADED == type);
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(extension_misc::UNLOAD_REASON_DISABLE == reason ||
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         extension_misc::UNLOAD_REASON_UNINSTALL == reason);
67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (code != SYNC_STATUS_OK &&
68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      code != SYNC_STATUS_UNKNOWN_ORIGIN) {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (reason) {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case extension_misc::UNLOAD_REASON_DISABLE:
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        util::Log(logging::LOG_WARNING,
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                  FROM_HERE,
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                  "Disabling origin for UNLOAD(DISABLE) failed: %s",
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                  origin.spec().c_str());
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case extension_misc::UNLOAD_REASON_UNINSTALL:
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        util::Log(logging::LOG_WARNING,
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                  FROM_HERE,
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                  "Uninstall origin for UNLOAD(UNINSTALL) failed: %s",
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                  origin.spec().c_str());
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default:
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DidHandleOriginForExtensionEnabledEvent(
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int type,
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& origin,
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncStatusCode code) {
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(chrome::NOTIFICATION_EXTENSION_ENABLED == type);
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (code != SYNC_STATUS_OK)
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    util::Log(logging::LOG_WARNING,
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              FROM_HERE,
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              "Enabling origin for ENABLED failed: %s",
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              origin.spec().c_str());
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemService::Shutdown() {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local_file_service_->Shutdown();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local_file_service_.reset();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  remote_file_service_.reset();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProfileSyncServiceBase* profile_sync_service =
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProfileSyncServiceFactory::GetForProfile(profile_);
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (profile_sync_service)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    profile_sync_service->RemoveObserver(this);
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_ = NULL;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncFileSystemService::~SyncFileSystemService() {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!profile_);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemService::InitializeForApp(
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fileapi::FileSystemContext* file_system_context,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& app_origin,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SyncStatusCallback& callback) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(local_file_service_);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(remote_file_service_);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(app_origin == app_origin.GetOrigin());
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "InitializeForApp: " << app_origin.spec();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local_file_service_->MaybeInitializeFileSystemContext(
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      app_origin, file_system_context,
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&SyncFileSystemService::DidInitializeFileSystem,
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 AsWeakPtr(), app_origin, callback));
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SyncServiceState SyncFileSystemService::GetSyncServiceState() {
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return RemoteStateToSyncServiceState(remote_file_service_->GetCurrentState());
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void SyncFileSystemService::GetExtensionStatusMap(
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    std::map<GURL, std::string>* status_map) {
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(status_map);
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  remote_file_service_->GetOriginStatusMap(status_map);
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::GetFileSyncStatus(
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FileSystemURL& url, const SyncFileStatusCallback& callback) {
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(local_file_service_);
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(remote_file_service_);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // It's possible to get an invalid FileEntry.
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!url.is_valid()) {
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback,
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   SYNC_FILE_ERROR_INVALID_URL,
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   SYNC_FILE_STATUS_UNKNOWN));
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (remote_file_service_->IsConflicting(url)) {
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback,
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   SYNC_STATUS_OK,
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   SYNC_FILE_STATUS_CONFLICTING));
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  local_file_service_->HasPendingLocalChanges(
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url,
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&SyncFileSystemService::DidGetLocalChangeStatus,
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 AsWeakPtr(), callback));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::AddSyncEventObserver(SyncEventObserver* observer) {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.AddObserver(observer);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::RemoveSyncEventObserver(
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncEventObserver* observer) {
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.RemoveObserver(observer);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ConflictResolutionPolicy
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SyncFileSystemService::GetConflictResolutionPolicy() const {
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return remote_file_service_->GetConflictResolutionPolicy();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SyncStatusCode SyncFileSystemService::SetConflictResolutionPolicy(
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ConflictResolutionPolicy policy) {
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return remote_file_service_->SetConflictResolutionPolicy(policy);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncFileSystemService::SyncFileSystemService(Profile* profile)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : profile_(profile),
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_local_changes_(0),
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pending_remote_changes_(0),
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      local_sync_running_(false),
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      remote_sync_running_(false),
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_waiting_remote_sync_enabled_(false),
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sync_enabled_(true) {
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncFileSystemService::Initialize(
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<LocalFileSyncService> local_file_service,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<RemoteFileSyncService> remote_file_service) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(local_file_service);
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(remote_file_service);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(profile_);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  local_file_service_ = local_file_service.Pass();
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  remote_file_service_ = remote_file_service.Pass();
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  local_file_service_->AddChangeObserver(this);
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  local_file_service_->SetLocalChangeProcessor(
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      remote_file_service_->GetLocalChangeProcessor());
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remote_file_service_->AddServiceObserver(this);
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remote_file_service_->AddFileStatusObserver(this);
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remote_file_service_->SetRemoteChangeProcessor(local_file_service_.get());
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProfileSyncServiceBase* profile_sync_service =
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProfileSyncServiceFactory::GetForProfile(profile_);
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (profile_sync_service) {
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateSyncEnabledStatus(profile_sync_service);
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    profile_sync_service->AddObserver(this);
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 content::Source<Profile>(profile_));
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 content::Source<Profile>(profile_));
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_ENABLED,
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 content::Source<Profile>(profile_));
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidInitializeFileSystem(
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& app_origin,
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const SyncStatusCallback& callback,
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncStatusCode status) {
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "DidInitializeFileSystem: "
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << app_origin.spec() << " " << status;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (status != SYNC_STATUS_OK) {
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(status);
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Local side of initialization for the app is done.
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Continue on initializing the remote side.
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remote_file_service_->RegisterOriginForTrackingChanges(
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      app_origin,
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&SyncFileSystemService::DidRegisterOrigin,
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 AsWeakPtr(), app_origin, callback));
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidRegisterOrigin(
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& app_origin,
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const SyncStatusCallback& callback,
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncStatusCode status) {
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "DidRegisterOrigin: " << app_origin.spec() << " " << status;
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(status);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::SetSyncEnabledForTesting(bool enabled) {
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_enabled_ = enabled;
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remote_file_service_->SetSyncEnabled(sync_enabled_);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::MaybeStartSync() {
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!profile_ || !sync_enabled_)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (pending_local_changes_ + pending_remote_changes_ == 0)
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DVLOG(2) << "MaybeStartSync() called (remote service state:"
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           << remote_file_service_->GetCurrentState() << ")";
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (remote_file_service_->GetCurrentState()) {
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case REMOTE_SERVICE_OK:
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case REMOTE_SERVICE_TEMPORARY_UNAVAILABLE:
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (sync_retry_timer_.IsRunning())
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return;
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      sync_retry_timer_.Start(
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          FROM_HERE,
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          base::TimeDelta::FromSeconds(kRetryTimerIntervalInSeconds),
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          this, &SyncFileSystemService::MaybeStartSync);
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case REMOTE_SERVICE_AUTHENTICATION_REQUIRED:
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case REMOTE_SERVICE_DISABLED:
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // No point to run sync.
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StartRemoteSync();
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StartLocalSync();
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SyncFileSystemService::StartRemoteSync() {
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // See if we cannot / should not start a new remote sync.
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (remote_sync_running_ || pending_remote_changes_ == 0)
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we have registered a URL for waiting until sync is enabled on a
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // file (and the registerred URL seems to be still valid) it won't be
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // worth trying to start another remote sync.
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_waiting_remote_sync_enabled_)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(sync_enabled_);
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "Calling ProcessRemoteChange";
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remote_sync_running_ = true;
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remote_file_service_->ProcessRemoteChange(
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&SyncFileSystemService::DidProcessRemoteChange,
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 AsWeakPtr()));
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SyncFileSystemService::StartLocalSync() {
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // See if we cannot / should not start a new local sync.
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (local_sync_running_ || pending_local_changes_ == 0)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(sync_enabled_);
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "Calling ProcessLocalChange";
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  local_sync_running_ = true;
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  local_file_service_->ProcessLocalChange(
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&SyncFileSystemService::DidProcessLocalChange,
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 AsWeakPtr()));
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidProcessRemoteChange(
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncStatusCode status,
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FileSystemURL& url) {
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "DidProcessRemoteChange: "
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << " status=" << status
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << " (" << SyncStatusCodeToString(status) << ")"
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << " url=" << url.DebugString();
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(remote_sync_running_);
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remote_sync_running_ = false;
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (status != SYNC_STATUS_NO_CHANGE_TO_SYNC &&
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      remote_file_service_->GetCurrentState() != REMOTE_SERVICE_DISABLED) {
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(url.is_valid());
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    local_file_service_->ClearSyncFlagForURL(url);
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (status == SYNC_STATUS_NO_CHANGE_TO_SYNC) {
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We seem to have no changes to work on for now.
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(kinuko): Might be better setting a timer to call MaybeStartSync.
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (status == SYNC_STATUS_FILE_BUSY) {
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    is_waiting_remote_sync_enabled_ = true;
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    local_file_service_->RegisterURLForWaitingSync(
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        url, base::Bind(&SyncFileSystemService::OnSyncEnabledForRemoteSync,
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        AsWeakPtr()));
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::MessageLoopProxy::current()->PostTask(
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(&SyncFileSystemService::MaybeStartSync,
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            AsWeakPtr()));
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidProcessLocalChange(
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncStatusCode status, const FileSystemURL& url) {
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "DidProcessLocalChange:"
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << " status=" << status
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << " (" << SyncStatusCodeToString(status) << ")"
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << " url=" << url.DebugString();
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(local_sync_running_);
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  local_sync_running_ = false;
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (status == SYNC_STATUS_NO_CHANGE_TO_SYNC) {
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We seem to have no changes to work on for now.
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(url.is_valid());
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  local_file_service_->ClearSyncFlagForURL(url);
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::MessageLoopProxy::current()->PostTask(
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(&SyncFileSystemService::MaybeStartSync,
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            AsWeakPtr()));
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::DidGetLocalChangeStatus(
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const SyncFileStatusCallback& callback,
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncStatusCode status,
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool has_pending_local_changes) {
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      status,
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      has_pending_local_changes ?
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          SYNC_FILE_STATUS_HAS_PENDING_CHANGES : SYNC_FILE_STATUS_SYNCED);
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnSyncEnabledForRemoteSync() {
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  is_waiting_remote_sync_enabled_ = false;
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MaybeStartSync();
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnLocalChangeAvailable(int64 pending_changes) {
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GE(pending_changes, 0);
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "OnLocalChangeAvailable: " << pending_changes;
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_local_changes_ = pending_changes;
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (pending_changes == 0)
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::MessageLoopProxy::current()->PostTask(
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(&SyncFileSystemService::MaybeStartSync,
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            AsWeakPtr()));
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnRemoteChangeQueueUpdated(int64 pending_changes) {
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_GE(pending_changes, 0);
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "OnRemoteChangeQueueUpdated: " << pending_changes;
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pending_remote_changes_ = pending_changes;
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (pending_changes == 0)
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The smallest change available might have changed from the previous one.
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Reset the is_waiting_remote_sync_enabled_ flag so that we can retry.
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  is_waiting_remote_sync_enabled_ = false;
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::MessageLoopProxy::current()->PostTask(
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(&SyncFileSystemService::MaybeStartSync,
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            AsWeakPtr()));
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnRemoteServiceStateUpdated(
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RemoteServiceState state,
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& description) {
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "OnRemoteServiceStateUpdated: " << state
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << " " << description;
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (state == REMOTE_SERVICE_OK) {
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE, base::Bind(&SyncFileSystemService::MaybeStartSync,
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              AsWeakPtr()));
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SyncEventObserver, observers_,
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      OnSyncStateUpdated(GURL(),
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         RemoteStateToSyncServiceState(state),
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         description));
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::Observe(
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int type,
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::NotificationSource& source,
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::NotificationDetails& details) {
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Event notification sequence.
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // (User action)    (Notification type)
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Install:         INSTALLED.
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Update:          INSTALLED.
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Uninstall:       UNLOADED(UNINSTALL).
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Launch, Close:   No notification.
471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Enable:          ENABLED.
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Disable:         UNLOADED(DISABLE).
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Reload, Restart: UNLOADED(DISABLE) -> INSTALLED -> ENABLED.
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (type) {
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case chrome::NOTIFICATION_EXTENSION_INSTALLED:
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      HandleExtensionInstalled(details);
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case chrome::NOTIFICATION_EXTENSION_UNLOADED:
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HandleExtensionUnloaded(type, details);
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case chrome::NOTIFICATION_EXTENSION_ENABLED:
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HandleExtensionEnabled(type, details);
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED() << "Unknown notification.";
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SyncFileSystemService::HandleExtensionInstalled(
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const content::NotificationDetails& details) {
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const extensions::Extension* extension =
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::Details<const extensions::InstalledExtensionInfo>(details)->
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          extension;
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GURL app_origin =
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::Extension::GetBaseURLFromExtensionId(extension->id());
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DVLOG(1) << "Handle extension notification for INSTALLED: " << app_origin;
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // NOTE: When an app is uninstalled and re-installed in a sequence,
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // |local_file_service_| may still keeps |app_origin| as disabled origin.
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  local_file_service_->SetOriginEnabled(app_origin, true);
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::HandleExtensionUnloaded(
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int type,
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::NotificationDetails& details) {
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::Details<const extensions::UnloadedExtensionInfo> info(details);
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string extension_id = info->extension->id();
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL app_origin =
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::Extension::GetBaseURLFromExtensionId(extension_id);
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (info->reason) {
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case extension_misc::UNLOAD_REASON_DISABLE:
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DVLOG(1) << "Handle extension notification for UNLOAD(DISABLE): "
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               << app_origin;
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      remote_file_service_->DisableOriginForTrackingChanges(
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          app_origin,
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(&DidHandleOriginForExtensionUnloadedEvent,
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     type, info->reason, app_origin));
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      local_file_service_->SetOriginEnabled(app_origin, false);
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case extension_misc::UNLOAD_REASON_UNINSTALL:
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DVLOG(1) << "Handle extension notification for UNLOAD(UNINSTALL): "
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               << app_origin;
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      remote_file_service_->UninstallOrigin(
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          app_origin,
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(&DidHandleOriginForExtensionUnloadedEvent,
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     type, info->reason, app_origin));
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      local_file_service_->SetOriginEnabled(app_origin, false);
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Nothing to do.
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::HandleExtensionEnabled(
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int type,
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::NotificationDetails& details) {
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string extension_id =
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::Details<const extensions::Extension>(details)->id();
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL app_origin =
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extensions::Extension::GetBaseURLFromExtensionId(extension_id);
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "Handle extension notification for ENABLED: " << app_origin;
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remote_file_service_->EnableOriginForTrackingChanges(
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      app_origin,
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&DidHandleOriginForExtensionEnabledEvent, type, app_origin));
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  local_file_service_->SetOriginEnabled(app_origin, true);
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnStateChanged() {
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProfileSyncServiceBase* profile_sync_service =
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProfileSyncServiceFactory::GetForProfile(profile_);
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (profile_sync_service)
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateSyncEnabledStatus(profile_sync_service);
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::OnFileStatusChanged(
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const FileSystemURL& url,
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncFileStatus sync_status,
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncAction action_taken,
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SyncDirection direction) {
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SyncEventObserver, observers_,
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      OnFileSynced(url, sync_status, action_taken, direction));
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SyncFileSystemService::UpdateSyncEnabledStatus(
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ProfileSyncServiceBase* profile_sync_service) {
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!profile_sync_service->HasSyncSetupCompleted())
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  sync_enabled_ = profile_sync_service->GetActiveDataTypes().Has(
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      syncer::APPS);
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remote_file_service_->SetSyncEnabled(sync_enabled_);
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (sync_enabled_) {
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE, base::Bind(&SyncFileSystemService::MaybeStartSync,
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              AsWeakPtr()));
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace sync_file_system
583