1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/sync_file_system/drive_backend/sync_worker.h"
10 #include "chrome/browser/drive/drive_service_interface.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/sync_file_system/drive_backend/callback_helper.h"
13 #include "chrome/browser/sync_file_system/drive_backend/conflict_resolver.h"
14 #include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
15 #include "chrome/browser/sync_file_system/drive_backend/list_changes_task.h"
16 #include "chrome/browser/sync_file_system/drive_backend/local_to_remote_syncer.h"
17 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
18 #include "chrome/browser/sync_file_system/drive_backend/register_app_task.h"
19 #include "chrome/browser/sync_file_system/drive_backend/remote_change_processor_on_worker.h"
20 #include "chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.h"
21 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
22 #include "chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.h"
23 #include "chrome/browser/sync_file_system/drive_backend/sync_task.h"
24 #include "chrome/browser/sync_file_system/drive_backend/uninstall_app_task.h"
25 #include "chrome/browser/sync_file_system/logger.h"
26 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
27 #include "storage/common/fileapi/file_system_util.h"
29 namespace sync_file_system
{
31 class RemoteChangeProcessor
;
33 namespace drive_backend
{
37 void EmptyStatusCallback(SyncStatusCode status
) {}
39 void InvokeIdleCallback(const base::Closure
& idle_callback
,
40 const SyncStatusCallback
& callback
) {
42 callback
.Run(SYNC_STATUS_OK
);
47 SyncWorker::SyncWorker(
48 const base::FilePath
& base_dir
,
49 const base::WeakPtr
<ExtensionServiceInterface
>& extension_service
,
50 leveldb::Env
* env_override
)
51 : base_dir_(base_dir
),
52 env_override_(env_override
),
53 service_state_(REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
),
54 should_check_conflict_(true),
55 should_check_remote_change_(true),
56 listing_remote_changes_(false),
58 extension_service_(extension_service
),
59 weak_ptr_factory_(this) {
60 sequence_checker_
.DetachFromSequence();
61 DCHECK(base_dir_
.IsAbsolute());
64 SyncWorker::~SyncWorker() {
68 void SyncWorker::Initialize(scoped_ptr
<SyncEngineContext
> context
) {
69 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
70 DCHECK(!task_manager_
);
72 context_
= context
.Pass();
74 task_manager_
.reset(new SyncTaskManager(
75 weak_ptr_factory_
.GetWeakPtr(), 0 /* maximum_background_task */,
76 context_
->GetWorkerTaskRunner(),
77 context_
->GetWorkerPool()));
78 task_manager_
->Initialize(SYNC_STATUS_OK
);
83 void SyncWorker::RegisterOrigin(
85 const SyncStatusCallback
& callback
) {
86 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
88 if (!GetMetadataDatabase())
91 scoped_ptr
<RegisterAppTask
> task(
92 new RegisterAppTask(context_
.get(), origin
.host()));
93 if (task
->CanFinishImmediately()) {
94 callback
.Run(SYNC_STATUS_OK
);
98 task_manager_
->ScheduleSyncTask(
99 FROM_HERE
, task
.Pass(), SyncTaskManager::PRIORITY_HIGH
, callback
);
102 void SyncWorker::EnableOrigin(
104 const SyncStatusCallback
& callback
) {
105 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
107 task_manager_
->ScheduleTask(
109 base::Bind(&SyncWorker::DoEnableApp
,
110 weak_ptr_factory_
.GetWeakPtr(),
112 SyncTaskManager::PRIORITY_HIGH
,
116 void SyncWorker::DisableOrigin(
118 const SyncStatusCallback
& callback
) {
119 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
121 task_manager_
->ScheduleTask(
123 base::Bind(&SyncWorker::DoDisableApp
,
124 weak_ptr_factory_
.GetWeakPtr(),
126 SyncTaskManager::PRIORITY_HIGH
,
130 void SyncWorker::UninstallOrigin(
132 RemoteFileSyncService::UninstallFlag flag
,
133 const SyncStatusCallback
& callback
) {
134 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
136 task_manager_
->ScheduleSyncTask(
138 scoped_ptr
<SyncTask
>(
139 new UninstallAppTask(context_
.get(), origin
.host(), flag
)),
140 SyncTaskManager::PRIORITY_HIGH
,
144 void SyncWorker::ProcessRemoteChange(const SyncFileCallback
& callback
) {
145 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
147 RemoteToLocalSyncer
* syncer
= new RemoteToLocalSyncer(context_
.get());
148 task_manager_
->ScheduleSyncTask(
150 scoped_ptr
<SyncTask
>(syncer
),
151 SyncTaskManager::PRIORITY_MED
,
152 base::Bind(&SyncWorker::DidProcessRemoteChange
,
153 weak_ptr_factory_
.GetWeakPtr(),
158 void SyncWorker::SetRemoteChangeProcessor(
159 RemoteChangeProcessorOnWorker
* remote_change_processor_on_worker
) {
160 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
162 context_
->SetRemoteChangeProcessor(remote_change_processor_on_worker
);
165 RemoteServiceState
SyncWorker::GetCurrentState() const {
166 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
169 return REMOTE_SERVICE_DISABLED
;
170 return service_state_
;
173 void SyncWorker::GetOriginStatusMap(
174 const RemoteFileSyncService::StatusMapCallback
& callback
) {
175 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
177 if (!GetMetadataDatabase())
180 std::vector
<std::string
> app_ids
;
181 GetMetadataDatabase()->GetRegisteredAppIDs(&app_ids
);
183 scoped_ptr
<RemoteFileSyncService::OriginStatusMap
>
184 status_map(new RemoteFileSyncService::OriginStatusMap
);
185 for (std::vector
<std::string
>::const_iterator itr
= app_ids
.begin();
186 itr
!= app_ids
.end(); ++itr
) {
187 const std::string
& app_id
= *itr
;
188 GURL origin
= extensions::Extension::GetBaseURLFromExtensionId(app_id
);
189 (*status_map
)[origin
] =
190 GetMetadataDatabase()->IsAppEnabled(app_id
) ? "Enabled" : "Disabled";
193 callback
.Run(status_map
.Pass());
196 scoped_ptr
<base::ListValue
> SyncWorker::DumpFiles(const GURL
& origin
) {
197 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
199 if (!GetMetadataDatabase())
200 return scoped_ptr
<base::ListValue
>();
201 return GetMetadataDatabase()->DumpFiles(origin
.host());
204 scoped_ptr
<base::ListValue
> SyncWorker::DumpDatabase() {
205 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
207 if (!GetMetadataDatabase())
208 return scoped_ptr
<base::ListValue
>();
209 return GetMetadataDatabase()->DumpDatabase();
212 void SyncWorker::SetSyncEnabled(bool enabled
) {
213 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
215 if (sync_enabled_
== enabled
)
218 RemoteServiceState old_state
= GetCurrentState();
219 sync_enabled_
= enabled
;
220 if (old_state
== GetCurrentState())
228 enabled
? "Sync is enabled" : "Sync is disabled"));
231 void SyncWorker::PromoteDemotedChanges(const base::Closure
& callback
) {
232 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
234 MetadataDatabase
* metadata_db
= GetMetadataDatabase();
235 if (metadata_db
&& metadata_db
->HasDemotedDirtyTracker()) {
236 metadata_db
->PromoteDemotedTrackers();
240 OnPendingFileListUpdated(metadata_db
->CountDirtyTracker()));
245 void SyncWorker::ApplyLocalChange(const FileChange
& local_change
,
246 const base::FilePath
& local_path
,
247 const SyncFileMetadata
& local_metadata
,
248 const storage::FileSystemURL
& url
,
249 const SyncStatusCallback
& callback
) {
250 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
252 LocalToRemoteSyncer
* syncer
= new LocalToRemoteSyncer(
253 context_
.get(), local_metadata
, local_change
, local_path
, url
);
254 task_manager_
->ScheduleSyncTask(
256 scoped_ptr
<SyncTask
>(syncer
),
257 SyncTaskManager::PRIORITY_MED
,
258 base::Bind(&SyncWorker::DidApplyLocalChange
,
259 weak_ptr_factory_
.GetWeakPtr(),
264 void SyncWorker::MaybeScheduleNextTask() {
265 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
267 if (GetCurrentState() == REMOTE_SERVICE_DISABLED
)
270 // TODO(tzik): Notify observer of OnRemoteChangeQueueUpdated.
271 // TODO(tzik): Add an interface to get the number of dirty trackers to
274 if (MaybeStartFetchChanges())
277 if (!call_on_idle_callback_
.is_null()) {
278 base::Closure callback
= call_on_idle_callback_
;
279 call_on_idle_callback_
.Reset();
284 void SyncWorker::NotifyLastOperationStatus(
285 SyncStatusCode status
,
287 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
289 UpdateServiceStateFromSyncStatusCode(status
, used_network
);
291 if (GetMetadataDatabase()) {
293 Observer
, observers_
,
294 OnPendingFileListUpdated(GetMetadataDatabase()->CountDirtyTracker()));
298 void SyncWorker::RecordTaskLog(scoped_ptr
<TaskLogger::TaskLog
> task_log
) {
299 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
301 context_
->GetUITaskRunner()->PostTask(
303 base::Bind(&TaskLogger::RecordLog
,
304 context_
->GetTaskLogger(),
305 base::Passed(&task_log
)));
308 void SyncWorker::ActivateService(RemoteServiceState service_state
,
309 const std::string
& description
) {
310 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
311 UpdateServiceState(service_state
, description
);
312 if (!GetMetadataDatabase()) {
313 PostInitializeTask();
317 should_check_remote_change_
= true;
318 MaybeScheduleNextTask();
321 void SyncWorker::DeactivateService(const std::string
& description
) {
322 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
323 UpdateServiceState(REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
, description
);
326 void SyncWorker::DetachFromSequence() {
327 task_manager_
->DetachFromSequence();
328 context_
->DetachFromSequence();
329 sequence_checker_
.DetachFromSequence();
332 void SyncWorker::AddObserver(Observer
* observer
) {
333 observers_
.AddObserver(observer
);
336 void SyncWorker::DoDisableApp(const std::string
& app_id
,
337 const SyncStatusCallback
& callback
) {
338 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
340 if (!GetMetadataDatabase()) {
341 callback
.Run(SYNC_STATUS_OK
);
345 SyncStatusCode status
= GetMetadataDatabase()->DisableApp(app_id
);
346 callback
.Run(status
);
349 void SyncWorker::DoEnableApp(const std::string
& app_id
,
350 const SyncStatusCallback
& callback
) {
351 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
353 if (!GetMetadataDatabase()) {
354 callback
.Run(SYNC_STATUS_OK
);
358 SyncStatusCode status
= GetMetadataDatabase()->EnableApp(app_id
);
359 callback
.Run(status
);
362 void SyncWorker::PostInitializeTask() {
363 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
364 DCHECK(!GetMetadataDatabase());
366 // This initializer task may not run if MetadataDatabase in context_ is
367 // already initialized when it runs.
368 SyncEngineInitializer
* initializer
=
369 new SyncEngineInitializer(context_
.get(),
370 base_dir_
.Append(kDatabaseName
),
372 task_manager_
->ScheduleSyncTask(
374 scoped_ptr
<SyncTask
>(initializer
),
375 SyncTaskManager::PRIORITY_HIGH
,
376 base::Bind(&SyncWorker::DidInitialize
,
377 weak_ptr_factory_
.GetWeakPtr(),
381 void SyncWorker::DidInitialize(SyncEngineInitializer
* initializer
,
382 SyncStatusCode status
) {
383 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
385 if (status
== SYNC_STATUS_ACCESS_FORBIDDEN
) {
386 UpdateServiceState(REMOTE_SERVICE_ACCESS_FORBIDDEN
, "Access forbidden");
389 if (status
!= SYNC_STATUS_OK
) {
390 UpdateServiceState(REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
,
391 "Could not initialize remote service");
395 scoped_ptr
<MetadataDatabase
> metadata_database
=
396 initializer
->PassMetadataDatabase();
397 if (metadata_database
) {
398 context_
->SetMetadataDatabase(metadata_database
.Pass());
402 UpdateServiceState(REMOTE_SERVICE_OK
, std::string());
403 UpdateRegisteredApps();
406 void SyncWorker::UpdateRegisteredApps() {
407 MetadataDatabase
* metadata_db
= GetMetadataDatabase();
408 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
411 scoped_ptr
<std::vector
<std::string
> > app_ids(new std::vector
<std::string
>);
412 metadata_db
->GetRegisteredAppIDs(app_ids
.get());
414 AppStatusMap
* app_status
= new AppStatusMap
;
415 base::Closure callback
=
416 base::Bind(&SyncWorker::DidQueryAppStatus
,
417 weak_ptr_factory_
.GetWeakPtr(),
418 base::Owned(app_status
));
420 context_
->GetUITaskRunner()->PostTask(
422 base::Bind(&SyncWorker::QueryAppStatusOnUIThread
,
424 base::Owned(app_ids
.release()),
426 RelayCallbackToTaskRunner(
427 context_
->GetWorkerTaskRunner(),
428 FROM_HERE
, callback
)));
431 void SyncWorker::QueryAppStatusOnUIThread(
432 const base::WeakPtr
<ExtensionServiceInterface
>& extension_service_ptr
,
433 const std::vector
<std::string
>* app_ids
,
434 AppStatusMap
* status
,
435 const base::Closure
& callback
) {
436 ExtensionServiceInterface
* extension_service
= extension_service_ptr
.get();
437 if (!extension_service
) {
442 for (std::vector
<std::string
>::const_iterator itr
= app_ids
->begin();
443 itr
!= app_ids
->end(); ++itr
) {
444 const std::string
& app_id
= *itr
;
445 if (!extension_service
->GetInstalledExtension(app_id
))
446 (*status
)[app_id
] = APP_STATUS_UNINSTALLED
;
447 else if (!extension_service
->IsExtensionEnabled(app_id
))
448 (*status
)[app_id
] = APP_STATUS_DISABLED
;
450 (*status
)[app_id
] = APP_STATUS_ENABLED
;
456 void SyncWorker::DidQueryAppStatus(const AppStatusMap
* app_status
) {
457 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
459 MetadataDatabase
* metadata_db
= GetMetadataDatabase();
462 // Update the status of every origin using status from ExtensionService.
463 for (AppStatusMap::const_iterator itr
= app_status
->begin();
464 itr
!= app_status
->end(); ++itr
) {
465 const std::string
& app_id
= itr
->first
;
466 GURL origin
= extensions::Extension::GetBaseURLFromExtensionId(app_id
);
468 if (itr
->second
== APP_STATUS_UNINSTALLED
) {
469 // Extension has been uninstalled.
470 // (At this stage we can't know if it was unpacked extension or not,
471 // so just purge the remote folder.)
472 UninstallOrigin(origin
,
473 RemoteFileSyncService::UNINSTALL_AND_PURGE_REMOTE
,
474 base::Bind(&EmptyStatusCallback
));
479 if (!metadata_db
->FindAppRootTracker(app_id
, &tracker
)) {
480 // App will register itself on first run.
484 DCHECK(itr
->second
== APP_STATUS_ENABLED
||
485 itr
->second
== APP_STATUS_DISABLED
);
486 bool is_app_enabled
= (itr
->second
== APP_STATUS_ENABLED
);
487 bool is_app_root_tracker_enabled
=
488 (tracker
.tracker_kind() == TRACKER_KIND_APP_ROOT
);
489 if (is_app_enabled
&& !is_app_root_tracker_enabled
)
490 EnableOrigin(origin
, base::Bind(&EmptyStatusCallback
));
491 else if (!is_app_enabled
&& is_app_root_tracker_enabled
)
492 DisableOrigin(origin
, base::Bind(&EmptyStatusCallback
));
496 void SyncWorker::DidProcessRemoteChange(RemoteToLocalSyncer
* syncer
,
497 const SyncFileCallback
& callback
,
498 SyncStatusCode status
) {
499 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
501 if (syncer
->is_sync_root_deletion()) {
502 MetadataDatabase::ClearDatabase(context_
->PassMetadataDatabase());
503 PostInitializeTask();
504 callback
.Run(status
, syncer
->url());
508 if (status
== SYNC_STATUS_OK
) {
509 if (syncer
->sync_action() != SYNC_ACTION_NONE
&&
510 syncer
->url().is_valid()) {
512 Observer
, observers_
,
516 SYNC_FILE_STATUS_SYNCED
,
517 syncer
->sync_action(),
518 SYNC_DIRECTION_REMOTE_TO_LOCAL
));
521 if (syncer
->sync_action() == SYNC_ACTION_DELETED
&&
522 syncer
->url().is_valid() &&
523 storage::VirtualPath::IsRootPath(syncer
->url().path())) {
524 RegisterOrigin(syncer
->url().origin(), base::Bind(&EmptyStatusCallback
));
526 should_check_conflict_
= true;
528 callback
.Run(status
, syncer
->url());
531 void SyncWorker::DidApplyLocalChange(LocalToRemoteSyncer
* syncer
,
532 const SyncStatusCallback
& callback
,
533 SyncStatusCode status
) {
534 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
536 if ((status
== SYNC_STATUS_OK
|| status
== SYNC_STATUS_RETRY
) &&
537 syncer
->url().is_valid() &&
538 syncer
->sync_action() != SYNC_ACTION_NONE
) {
539 storage::FileSystemURL updated_url
= syncer
->url();
540 if (!syncer
->target_path().empty()) {
541 updated_url
= CreateSyncableFileSystemURL(syncer
->url().origin(),
542 syncer
->target_path());
544 FOR_EACH_OBSERVER(Observer
, observers_
,
545 OnFileStatusChanged(updated_url
,
547 SYNC_FILE_STATUS_SYNCED
,
548 syncer
->sync_action(),
549 SYNC_DIRECTION_LOCAL_TO_REMOTE
));
552 if (status
== SYNC_STATUS_UNKNOWN_ORIGIN
&& syncer
->url().is_valid()) {
553 RegisterOrigin(syncer
->url().origin(),
554 base::Bind(&EmptyStatusCallback
));
557 if (syncer
->needs_remote_change_listing() &&
558 !listing_remote_changes_
) {
559 task_manager_
->ScheduleSyncTask(
561 scoped_ptr
<SyncTask
>(new ListChangesTask(context_
.get())),
562 SyncTaskManager::PRIORITY_HIGH
,
563 base::Bind(&SyncWorker::DidFetchChanges
,
564 weak_ptr_factory_
.GetWeakPtr()));
565 should_check_remote_change_
= false;
566 listing_remote_changes_
= true;
567 time_to_check_changes_
=
568 base::TimeTicks::Now() +
569 base::TimeDelta::FromSeconds(kListChangesRetryDelaySeconds
);
572 if (status
== SYNC_STATUS_OK
)
573 should_check_conflict_
= true;
575 callback
.Run(status
);
578 bool SyncWorker::MaybeStartFetchChanges() {
579 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
581 if (GetCurrentState() == REMOTE_SERVICE_DISABLED
)
584 if (!GetMetadataDatabase())
587 if (listing_remote_changes_
)
590 base::TimeTicks now
= base::TimeTicks::Now();
591 if (!should_check_remote_change_
&& now
< time_to_check_changes_
) {
592 if (!GetMetadataDatabase()->HasDirtyTracker() &&
593 should_check_conflict_
) {
594 should_check_conflict_
= false;
595 return task_manager_
->ScheduleSyncTaskIfIdle(
597 scoped_ptr
<SyncTask
>(new ConflictResolver(context_
.get())),
598 base::Bind(&SyncWorker::DidResolveConflict
,
599 weak_ptr_factory_
.GetWeakPtr()));
604 if (task_manager_
->ScheduleSyncTaskIfIdle(
606 scoped_ptr
<SyncTask
>(new ListChangesTask(context_
.get())),
607 base::Bind(&SyncWorker::DidFetchChanges
,
608 weak_ptr_factory_
.GetWeakPtr()))) {
609 should_check_remote_change_
= false;
610 listing_remote_changes_
= true;
611 time_to_check_changes_
=
612 now
+ base::TimeDelta::FromSeconds(kListChangesRetryDelaySeconds
);
618 void SyncWorker::DidResolveConflict(SyncStatusCode status
) {
619 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
621 if (status
== SYNC_STATUS_OK
|| status
== SYNC_STATUS_RETRY
)
622 should_check_conflict_
= true;
625 void SyncWorker::DidFetchChanges(SyncStatusCode status
) {
626 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
628 if (status
== SYNC_STATUS_OK
)
629 should_check_conflict_
= true;
630 listing_remote_changes_
= false;
633 void SyncWorker::UpdateServiceStateFromSyncStatusCode(
634 SyncStatusCode status
,
639 UpdateServiceState(REMOTE_SERVICE_OK
, std::string());
642 // Authentication error.
643 case SYNC_STATUS_AUTHENTICATION_FAILED
:
644 UpdateServiceState(REMOTE_SERVICE_AUTHENTICATION_REQUIRED
,
645 "Authentication required");
648 // OAuth token error.
649 case SYNC_STATUS_ACCESS_FORBIDDEN
:
650 UpdateServiceState(REMOTE_SERVICE_ACCESS_FORBIDDEN
,
654 // Errors which could make the service temporarily unavailable.
655 case SYNC_STATUS_SERVICE_TEMPORARILY_UNAVAILABLE
:
656 case SYNC_STATUS_NETWORK_ERROR
:
657 case SYNC_STATUS_ABORT
:
658 case SYNC_STATUS_FAILED
:
659 UpdateServiceState(REMOTE_SERVICE_TEMPORARY_UNAVAILABLE
,
660 "Network or temporary service error.");
663 // Errors which would require manual user intervention to resolve.
664 case SYNC_DATABASE_ERROR_CORRUPTION
:
665 case SYNC_DATABASE_ERROR_IO_ERROR
:
666 case SYNC_DATABASE_ERROR_FAILED
:
667 UpdateServiceState(REMOTE_SERVICE_DISABLED
,
668 "Unrecoverable database error");
672 // Other errors don't affect service state
677 void SyncWorker::UpdateServiceState(RemoteServiceState state
,
678 const std::string
& description
) {
679 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
681 RemoteServiceState old_state
= GetCurrentState();
682 service_state_
= state
;
684 if (old_state
== GetCurrentState())
687 util::Log(logging::LOG_VERBOSE
, FROM_HERE
,
688 "Service state changed: %d->%d: %s",
689 old_state
, GetCurrentState(), description
.c_str());
692 Observer
, observers_
,
693 UpdateServiceState(GetCurrentState(), description
));
696 void SyncWorker::CallOnIdleForTesting(const base::Closure
& callback
) {
697 if (task_manager_
->ScheduleTaskIfIdle(
699 base::Bind(&InvokeIdleCallback
, callback
),
700 base::Bind(&EmptyStatusCallback
)))
702 call_on_idle_callback_
= base::Bind(
703 &SyncWorker::CallOnIdleForTesting
,
704 weak_ptr_factory_
.GetWeakPtr(),
708 drive::DriveServiceInterface
* SyncWorker::GetDriveService() {
709 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
710 return context_
->GetDriveService();
713 drive::DriveUploaderInterface
* SyncWorker::GetDriveUploader() {
714 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
715 return context_
->GetDriveUploader();
718 MetadataDatabase
* SyncWorker::GetMetadataDatabase() {
719 DCHECK(sequence_checker_
.CalledOnValidSequencedThread());
720 return context_
->GetMetadataDatabase();
723 } // namespace drive_backend
724 } // namespace sync_file_system