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"
17 SyncRollbackManager::SyncRollbackManager()
18 : change_delegate_(NULL
) {
21 SyncRollbackManager::~SyncRollbackManager() {
24 void SyncRollbackManager::Init(
25 const base::FilePath
& database_location
,
26 const WeakHandle
<JsEventHandler
>& event_handler
,
27 const std::string
& sync_server_and_path
,
30 scoped_ptr
<HttpPostProviderFactory
> post_factory
,
31 const std::vector
<scoped_refptr
<ModelSafeWorker
> >& workers
,
32 ExtensionsActivity
* extensions_activity
,
33 SyncManager::ChangeDelegate
* change_delegate
,
34 const SyncCredentials
& credentials
,
35 const std::string
& invalidator_client_id
,
36 const std::string
& restored_key_for_bootstrapping
,
37 const std::string
& restored_keystore_key_for_bootstrapping
,
38 InternalComponentsFactory
* internal_components_factory
,
40 scoped_ptr
<UnrecoverableErrorHandler
> unrecoverable_error_handler
,
41 ReportUnrecoverableErrorFunction
42 report_unrecoverable_error_function
,
43 CancelationSignal
* cancelation_signal
) {
44 SyncRollbackManagerBase::Init(database_location
, event_handler
,
45 sync_server_and_path
, sync_server_port
,
46 use_ssl
, post_factory
.Pass(),
47 workers
, extensions_activity
, change_delegate
,
48 credentials
, invalidator_client_id
,
49 restored_key_for_bootstrapping
,
50 restored_keystore_key_for_bootstrapping
,
51 internal_components_factory
, encryptor
,
52 unrecoverable_error_handler
.Pass(),
53 report_unrecoverable_error_function
,
59 change_delegate_
= change_delegate
;
61 for (size_t i
= 0; i
< workers
.size(); ++i
) {
62 ModelSafeGroup group
= workers
[i
]->GetModelSafeGroup();
63 CHECK(workers_
.find(group
) == workers_
.end());
64 workers_
[group
] = workers
[i
];
67 rollback_ready_types_
= GetUserShare()->directory
->InitialSyncEndedTypes();
68 rollback_ready_types_
.RetainAll(BackupTypes());
71 void SyncRollbackManager::StartSyncingNormally(
72 const ModelSafeRoutingInfo
& routing_info
){
73 if (rollback_ready_types_
.Empty()) {
78 std::map
<ModelType
, syncable::Directory::Metahandles
> to_delete
;
80 WriteTransaction
trans(FROM_HERE
, GetUserShare());
81 syncable::Directory::Metahandles unsynced
;
82 GetUserShare()->directory
->GetUnsyncedMetaHandles(trans
.GetWrappedTrans(),
84 for (size_t i
= 0; i
< unsynced
.size(); ++i
) {
85 syncable::MutableEntry
e(trans
.GetWrappedWriteTrans(),
86 syncable::GET_BY_HANDLE
, unsynced
[i
]);
87 if (!e
.good() || e
.GetIsDel() || e
.GetId().ServerKnows())
90 // TODO(haitaol): roll back entries that are backed up but whose content
91 // is merged with local model during association.
93 ModelType type
= GetModelTypeFromSpecifics(e
.GetSpecifics());
94 if (!rollback_ready_types_
.Has(type
))
97 to_delete
[type
].push_back(unsynced
[i
]);
101 for (std::map
<ModelType
, syncable::Directory::Metahandles
>::iterator it
=
102 to_delete
.begin(); it
!= to_delete
.end(); ++it
) {
103 ModelSafeGroup group
= routing_info
.find(it
->first
)->second
;
104 CHECK(workers_
.find(group
) != workers_
.end());
105 workers_
[group
]->DoWorkAndWaitUntilDone(
106 base::Bind(&SyncRollbackManager::DeleteOnWorkerThread
,
107 base::Unretained(this),
108 it
->first
, it
->second
));
111 NotifyRollbackDone();
114 SyncerError
SyncRollbackManager::DeleteOnWorkerThread(
115 ModelType type
, std::vector
<int64
> handles
) {
116 CHECK(change_delegate_
);
119 ChangeRecordList deletes
;
120 WriteTransaction
trans(FROM_HERE
, GetUserShare());
121 for (size_t i
= 0; i
< handles
.size(); ++i
) {
122 syncable::MutableEntry
e(trans
.GetWrappedWriteTrans(),
123 syncable::GET_BY_HANDLE
, handles
[i
]);
124 if (!e
.good() || e
.GetIsDel())
128 del
.action
= ChangeRecord::ACTION_DELETE
;
130 del
.specifics
= e
.GetSpecifics();
131 deletes
.push_back(del
);
134 change_delegate_
->OnChangesApplied(type
, 1, &trans
,
135 MakeImmutable(&deletes
));
138 change_delegate_
->OnChangesComplete(type
);
142 void SyncRollbackManager::NotifyRollbackDone() {
143 SyncProtocolError error
;
144 error
.action
= ROLLBACK_DONE
;
145 FOR_EACH_OBSERVER(SyncManager::Observer
, *GetObservers(),
146 OnActionableError(error
));
149 } // namespace syncer