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 "sync/internal_api/sync_rollback_manager.h"
7 #include "sync/internal_api/public/base/model_type.h"
8 #include "sync/internal_api/public/read_node.h"
9 #include "sync/internal_api/public/read_transaction.h"
10 #include "sync/internal_api/public/util/syncer_error.h"
11 #include "sync/internal_api/public/write_transaction.h"
12 #include "sync/syncable/directory.h"
13 #include "sync/syncable/mutable_entry.h"
18 SyncRollbackManager::SyncRollbackManager()
19 : change_delegate_(NULL
) {
22 SyncRollbackManager::~SyncRollbackManager() {
25 void SyncRollbackManager::Init(
26 const base::FilePath
& database_location
,
27 const WeakHandle
<JsEventHandler
>& event_handler
,
28 const GURL
& service_url
,
29 scoped_ptr
<HttpPostProviderFactory
> post_factory
,
30 const std::vector
<scoped_refptr
<ModelSafeWorker
> >& workers
,
31 ExtensionsActivity
* extensions_activity
,
32 SyncManager::ChangeDelegate
* change_delegate
,
33 const SyncCredentials
& credentials
,
34 const std::string
& invalidator_client_id
,
35 const std::string
& restored_key_for_bootstrapping
,
36 const std::string
& restored_keystore_key_for_bootstrapping
,
37 InternalComponentsFactory
* internal_components_factory
,
39 scoped_ptr
<UnrecoverableErrorHandler
> unrecoverable_error_handler
,
40 ReportUnrecoverableErrorFunction report_unrecoverable_error_function
,
41 CancelationSignal
* cancelation_signal
) {
42 if (SyncRollbackManagerBase::InitInternal(
44 internal_components_factory
,
45 unrecoverable_error_handler
.Pass(),
46 report_unrecoverable_error_function
)) {
47 change_delegate_
= change_delegate
;
49 for (size_t i
= 0; i
< workers
.size(); ++i
) {
50 ModelSafeGroup group
= workers
[i
]->GetModelSafeGroup();
51 CHECK(workers_
.find(group
) == workers_
.end());
52 workers_
[group
] = workers
[i
];
55 rollback_ready_types_
= GetUserShare()->directory
->InitialSyncEndedTypes();
56 rollback_ready_types_
.RetainAll(BackupTypes());
60 void SyncRollbackManager::StartSyncingNormally(
61 const ModelSafeRoutingInfo
& routing_info
){
62 if (rollback_ready_types_
.Empty()) {
67 std::map
<ModelType
, syncable::Directory::Metahandles
> to_delete
;
69 WriteTransaction
trans(FROM_HERE
, GetUserShare());
70 syncable::Directory::Metahandles unsynced
;
71 GetUserShare()->directory
->GetUnsyncedMetaHandles(trans
.GetWrappedTrans(),
73 for (size_t i
= 0; i
< unsynced
.size(); ++i
) {
74 syncable::MutableEntry
e(trans
.GetWrappedWriteTrans(),
75 syncable::GET_BY_HANDLE
, unsynced
[i
]);
76 if (!e
.good() || e
.GetIsDel() || e
.GetId().ServerKnows())
79 // TODO(haitaol): roll back entries that are backed up but whose content
80 // is merged with local model during association.
82 ModelType type
= GetModelTypeFromSpecifics(e
.GetSpecifics());
83 if (!rollback_ready_types_
.Has(type
))
86 to_delete
[type
].push_back(unsynced
[i
]);
90 for (std::map
<ModelType
, syncable::Directory::Metahandles
>::iterator it
=
91 to_delete
.begin(); it
!= to_delete
.end(); ++it
) {
92 ModelSafeGroup group
= routing_info
.find(it
->first
)->second
;
93 CHECK(workers_
.find(group
) != workers_
.end());
94 workers_
[group
]->DoWorkAndWaitUntilDone(
95 base::Bind(&SyncRollbackManager::DeleteOnWorkerThread
,
96 base::Unretained(this),
97 it
->first
, it
->second
));
100 NotifyRollbackDone();
103 SyncerError
SyncRollbackManager::DeleteOnWorkerThread(
104 ModelType type
, std::vector
<int64
> handles
) {
105 CHECK(change_delegate_
);
108 ChangeRecordList deletes
;
109 WriteTransaction
trans(FROM_HERE
, GetUserShare());
110 for (size_t i
= 0; i
< handles
.size(); ++i
) {
111 syncable::MutableEntry
e(trans
.GetWrappedWriteTrans(),
112 syncable::GET_BY_HANDLE
, handles
[i
]);
113 if (!e
.good() || e
.GetIsDel())
117 del
.action
= ChangeRecord::ACTION_DELETE
;
119 del
.specifics
= e
.GetSpecifics();
120 deletes
.push_back(del
);
123 change_delegate_
->OnChangesApplied(type
, 1, &trans
,
124 MakeImmutable(&deletes
));
127 change_delegate_
->OnChangesComplete(type
);
131 void SyncRollbackManager::NotifyRollbackDone() {
132 SyncProtocolError error
;
133 error
.action
= ROLLBACK_DONE
;
134 FOR_EACH_OBSERVER(SyncManager::Observer
, *GetObservers(),
135 OnActionableError(error
));
138 } // namespace syncer