OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/sync/driver/backend_migrator.h" | 5 #include "components/sync/driver/backend_migrator.h" |
6 | 6 |
7 #include "base/location.h" | 7 #include "base/location.h" |
8 #include "base/single_thread_task_runner.h" | 8 #include "base/single_thread_task_runner.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" |
11 #include "base/tracked_objects.h" | 11 #include "base/tracked_objects.h" |
12 #include "components/sync/core/configure_reason.h" | 12 #include "components/sync/core/configure_reason.h" |
13 #include "components/sync/core/read_transaction.h" | 13 #include "components/sync/core/read_transaction.h" |
14 #include "components/sync/driver/sync_service.h" | 14 #include "components/sync/driver/sync_service.h" |
15 #include "components/sync/protocol/sync.pb.h" | 15 #include "components/sync/protocol/sync.pb.h" |
16 #include "components/sync/syncable/directory.h" // TODO(tim): Bug 131130. | 16 #include "components/sync/syncable/directory.h" // TODO(tim): Bug 131130. |
17 | 17 |
18 using syncer::ModelTypeSet; | 18 namespace syncer { |
19 | |
20 namespace browser_sync { | |
21 | |
22 using syncer::ModelTypeToString; | |
23 | 19 |
24 MigrationObserver::~MigrationObserver() {} | 20 MigrationObserver::~MigrationObserver() {} |
25 | 21 |
26 BackendMigrator::BackendMigrator(const std::string& name, | 22 BackendMigrator::BackendMigrator(const std::string& name, |
27 syncer::UserShare* user_share, | 23 UserShare* user_share, |
28 sync_driver::SyncService* service, | 24 SyncService* service, |
29 sync_driver::DataTypeManager* manager, | 25 DataTypeManager* manager, |
30 const base::Closure& migration_done_callback) | 26 const base::Closure& migration_done_callback) |
31 : name_(name), | 27 : name_(name), |
32 user_share_(user_share), | 28 user_share_(user_share), |
33 service_(service), | 29 service_(service), |
34 manager_(manager), | 30 manager_(manager), |
35 state_(IDLE), | 31 state_(IDLE), |
36 migration_done_callback_(migration_done_callback), | 32 migration_done_callback_(migration_done_callback), |
37 weak_ptr_factory_(this) {} | 33 weak_ptr_factory_(this) {} |
38 | 34 |
39 BackendMigrator::~BackendMigrator() {} | 35 BackendMigrator::~BackendMigrator() {} |
40 | 36 |
41 // Helper macros to log with the syncer thread name; useful when there | 37 // Helper macros to log with the syncer thread name; useful when there |
42 // are multiple syncer threads involved. | 38 // are multiple syncer threads involved. |
43 | 39 |
44 #define SLOG(severity) LOG(severity) << name_ << ": " | 40 #define SLOG(severity) LOG(severity) << name_ << ": " |
45 | 41 |
46 #define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " | 42 #define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " |
47 | 43 |
48 void BackendMigrator::MigrateTypes(syncer::ModelTypeSet types) { | 44 void BackendMigrator::MigrateTypes(ModelTypeSet types) { |
49 const ModelTypeSet old_to_migrate = to_migrate_; | 45 const ModelTypeSet old_to_migrate = to_migrate_; |
50 to_migrate_.PutAll(types); | 46 to_migrate_.PutAll(types); |
51 SDVLOG(1) << "MigrateTypes called with " << ModelTypeSetToString(types) | 47 SDVLOG(1) << "MigrateTypes called with " << ModelTypeSetToString(types) |
52 << ", old_to_migrate = " << ModelTypeSetToString(old_to_migrate) | 48 << ", old_to_migrate = " << ModelTypeSetToString(old_to_migrate) |
53 << ", to_migrate_ = " << ModelTypeSetToString(to_migrate_); | 49 << ", to_migrate_ = " << ModelTypeSetToString(to_migrate_); |
54 if (old_to_migrate == to_migrate_) { | 50 if (old_to_migrate == to_migrate_) { |
55 SDVLOG(1) << "MigrateTypes called with no new types; ignoring"; | 51 SDVLOG(1) << "MigrateTypes called with no new types; ignoring"; |
56 return; | 52 return; |
57 } | 53 } |
58 | 54 |
(...skipping 25 matching lines...) Expand all Loading... |
84 } | 80 } |
85 | 81 |
86 void BackendMigrator::ChangeState(State new_state) { | 82 void BackendMigrator::ChangeState(State new_state) { |
87 state_ = new_state; | 83 state_ = new_state; |
88 FOR_EACH_OBSERVER(MigrationObserver, migration_observers_, | 84 FOR_EACH_OBSERVER(MigrationObserver, migration_observers_, |
89 OnMigrationStateChange()); | 85 OnMigrationStateChange()); |
90 } | 86 } |
91 | 87 |
92 bool BackendMigrator::TryStart() { | 88 bool BackendMigrator::TryStart() { |
93 DCHECK_EQ(state_, WAITING_TO_START); | 89 DCHECK_EQ(state_, WAITING_TO_START); |
94 if (manager_->state() == sync_driver::DataTypeManager::CONFIGURED) { | 90 if (manager_->state() == DataTypeManager::CONFIGURED) { |
95 RestartMigration(); | 91 RestartMigration(); |
96 return true; | 92 return true; |
97 } | 93 } |
98 return false; | 94 return false; |
99 } | 95 } |
100 | 96 |
101 void BackendMigrator::RestartMigration() { | 97 void BackendMigrator::RestartMigration() { |
102 // We'll now disable any running types that need to be migrated. | 98 // We'll now disable any running types that need to be migrated. |
103 ChangeState(DISABLING_TYPES); | 99 ChangeState(DISABLING_TYPES); |
104 SDVLOG(1) << "BackendMigrator disabling types " | 100 SDVLOG(1) << "BackendMigrator disabling types " |
105 << ModelTypeSetToString(to_migrate_); | 101 << ModelTypeSetToString(to_migrate_); |
106 | 102 |
107 manager_->PurgeForMigration(to_migrate_, syncer::CONFIGURE_REASON_MIGRATION); | 103 manager_->PurgeForMigration(to_migrate_, CONFIGURE_REASON_MIGRATION); |
108 } | 104 } |
109 | 105 |
110 void BackendMigrator::OnConfigureDone( | 106 void BackendMigrator::OnConfigureDone( |
111 const sync_driver::DataTypeManager::ConfigureResult& result) { | 107 const DataTypeManager::ConfigureResult& result) { |
112 if (state_ == IDLE) | 108 if (state_ == IDLE) |
113 return; | 109 return; |
114 | 110 |
115 // |manager_|'s methods aren't re-entrant, and we're notified from | 111 // |manager_|'s methods aren't re-entrant, and we're notified from |
116 // them, so post a task to avoid problems. | 112 // them, so post a task to avoid problems. |
117 SDVLOG(1) << "Posting OnConfigureDoneImpl"; | 113 SDVLOG(1) << "Posting OnConfigureDoneImpl"; |
118 base::ThreadTaskRunnerHandle::Get()->PostTask( | 114 base::ThreadTaskRunnerHandle::Get()->PostTask( |
119 FROM_HERE, base::Bind(&BackendMigrator::OnConfigureDoneImpl, | 115 FROM_HERE, base::Bind(&BackendMigrator::OnConfigureDoneImpl, |
120 weak_ptr_factory_.GetWeakPtr(), result)); | 116 weak_ptr_factory_.GetWeakPtr(), result)); |
121 } | 117 } |
122 | 118 |
123 namespace { | 119 namespace { |
124 | 120 |
125 syncer::ModelTypeSet GetUnsyncedDataTypes(syncer::UserShare* user_share) { | 121 ModelTypeSet GetUnsyncedDataTypes(UserShare* user_share) { |
126 syncer::ReadTransaction trans(FROM_HERE, user_share); | 122 ReadTransaction trans(FROM_HERE, user_share); |
127 syncer::ModelTypeSet unsynced_data_types; | 123 ModelTypeSet unsynced_data_types; |
128 for (int i = syncer::FIRST_REAL_MODEL_TYPE; i < syncer::MODEL_TYPE_COUNT; | 124 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { |
129 ++i) { | 125 ModelType type = ModelTypeFromInt(i); |
130 syncer::ModelType type = syncer::ModelTypeFromInt(i); | |
131 sync_pb::DataTypeProgressMarker progress_marker; | 126 sync_pb::DataTypeProgressMarker progress_marker; |
132 trans.GetDirectory()->GetDownloadProgress(type, &progress_marker); | 127 trans.GetDirectory()->GetDownloadProgress(type, &progress_marker); |
133 if (progress_marker.token().empty()) { | 128 if (progress_marker.token().empty()) { |
134 unsynced_data_types.Put(type); | 129 unsynced_data_types.Put(type); |
135 } | 130 } |
136 } | 131 } |
137 return unsynced_data_types; | 132 return unsynced_data_types; |
138 } | 133 } |
139 | 134 |
140 } // namespace | 135 } // namespace |
141 | 136 |
142 void BackendMigrator::OnConfigureDoneImpl( | 137 void BackendMigrator::OnConfigureDoneImpl( |
143 const sync_driver::DataTypeManager::ConfigureResult& result) { | 138 const DataTypeManager::ConfigureResult& result) { |
144 SDVLOG(1) << "OnConfigureDone with requested types " | 139 SDVLOG(1) << "OnConfigureDone with requested types " |
145 << ModelTypeSetToString(result.requested_types) << ", status " | 140 << ModelTypeSetToString(result.requested_types) << ", status " |
146 << result.status | 141 << result.status |
147 << ", and to_migrate_ = " << ModelTypeSetToString(to_migrate_); | 142 << ", and to_migrate_ = " << ModelTypeSetToString(to_migrate_); |
148 if (state_ == WAITING_TO_START) { | 143 if (state_ == WAITING_TO_START) { |
149 if (!TryStart()) | 144 if (!TryStart()) |
150 SDVLOG(1) << "Manager still not configured; still waiting"; | 145 SDVLOG(1) << "Manager still not configured; still waiting"; |
151 return; | 146 return; |
152 } | 147 } |
153 | 148 |
154 DCHECK_GT(state_, WAITING_TO_START); | 149 DCHECK_GT(state_, WAITING_TO_START); |
155 | 150 |
156 const ModelTypeSet intersection = | 151 const ModelTypeSet intersection = |
157 Intersection(result.requested_types, to_migrate_); | 152 Intersection(result.requested_types, to_migrate_); |
158 // This intersection check is to determine if our disable request | 153 // This intersection check is to determine if our disable request |
159 // was interrupted by a user changing preferred types. | 154 // was interrupted by a user changing preferred types. |
160 if (state_ == DISABLING_TYPES && !intersection.Empty()) { | 155 if (state_ == DISABLING_TYPES && !intersection.Empty()) { |
161 SDVLOG(1) << "Disable request interrupted by user changing types"; | 156 SDVLOG(1) << "Disable request interrupted by user changing types"; |
162 RestartMigration(); | 157 RestartMigration(); |
163 return; | 158 return; |
164 } | 159 } |
165 | 160 |
166 if (result.status != sync_driver::DataTypeManager::OK) { | 161 if (result.status != DataTypeManager::OK) { |
167 // If this fails, and we're disabling types, a type may or may not be | 162 // If this fails, and we're disabling types, a type may or may not be |
168 // disabled until the user restarts the browser. If this wasn't an abort, | 163 // disabled until the user restarts the browser. If this wasn't an abort, |
169 // any failure will be reported as an unrecoverable error to the UI. If it | 164 // any failure will be reported as an unrecoverable error to the UI. If it |
170 // was an abort, then typically things are shutting down anyway. There isn't | 165 // was an abort, then typically things are shutting down anyway. There isn't |
171 // much we can do in any case besides wait until a restart to try again. | 166 // much we can do in any case besides wait until a restart to try again. |
172 // The server will send down MIGRATION_DONE again for types needing | 167 // The server will send down MIGRATION_DONE again for types needing |
173 // migration as the type will still be enabled on restart. | 168 // migration as the type will still be enabled on restart. |
174 SLOG(WARNING) << "Unable to migrate, configuration failed!"; | 169 SLOG(WARNING) << "Unable to migrate, configuration failed!"; |
175 ChangeState(IDLE); | 170 ChangeState(IDLE); |
176 to_migrate_.Clear(); | 171 to_migrate_.Clear(); |
177 return; | 172 return; |
178 } | 173 } |
179 | 174 |
180 if (state_ == DISABLING_TYPES) { | 175 if (state_ == DISABLING_TYPES) { |
181 const syncer::ModelTypeSet unsynced_types = | 176 const ModelTypeSet unsynced_types = GetUnsyncedDataTypes(user_share_); |
182 GetUnsyncedDataTypes(user_share_); | |
183 if (!unsynced_types.HasAll(to_migrate_)) { | 177 if (!unsynced_types.HasAll(to_migrate_)) { |
184 SLOG(WARNING) << "Set of unsynced types: " | 178 SLOG(WARNING) << "Set of unsynced types: " |
185 << syncer::ModelTypeSetToString(unsynced_types) | 179 << ModelTypeSetToString(unsynced_types) |
186 << " does not contain types to migrate: " | 180 << " does not contain types to migrate: " |
187 << syncer::ModelTypeSetToString(to_migrate_) | 181 << ModelTypeSetToString(to_migrate_) |
188 << "; not re-enabling yet"; | 182 << "; not re-enabling yet"; |
189 return; | 183 return; |
190 } | 184 } |
191 | 185 |
192 ChangeState(REENABLING_TYPES); | 186 ChangeState(REENABLING_TYPES); |
193 // Don't use |to_migrate_| for the re-enabling because the user | 187 // Don't use |to_migrate_| for the re-enabling because the user |
194 // may have chosen to disable types during the migration. | 188 // may have chosen to disable types during the migration. |
195 const ModelTypeSet full_set = service_->GetPreferredDataTypes(); | 189 const ModelTypeSet full_set = service_->GetPreferredDataTypes(); |
196 SDVLOG(1) << "BackendMigrator re-enabling types: " | 190 SDVLOG(1) << "BackendMigrator re-enabling types: " |
197 << syncer::ModelTypeSetToString(full_set); | 191 << ModelTypeSetToString(full_set); |
198 manager_->Configure(full_set, syncer::CONFIGURE_REASON_MIGRATION); | 192 manager_->Configure(full_set, CONFIGURE_REASON_MIGRATION); |
199 } else if (state_ == REENABLING_TYPES) { | 193 } else if (state_ == REENABLING_TYPES) { |
200 // We're done! | 194 // We're done! |
201 ChangeState(IDLE); | 195 ChangeState(IDLE); |
202 | 196 |
203 SDVLOG(1) << "BackendMigrator: Migration complete for: " | 197 SDVLOG(1) << "BackendMigrator: Migration complete for: " |
204 << syncer::ModelTypeSetToString(to_migrate_); | 198 << ModelTypeSetToString(to_migrate_); |
205 to_migrate_.Clear(); | 199 to_migrate_.Clear(); |
206 | 200 |
207 if (!migration_done_callback_.is_null()) | 201 if (!migration_done_callback_.is_null()) |
208 migration_done_callback_.Run(); | 202 migration_done_callback_.Run(); |
209 } | 203 } |
210 } | 204 } |
211 | 205 |
212 BackendMigrator::State BackendMigrator::state() const { | 206 BackendMigrator::State BackendMigrator::state() const { |
213 return state_; | 207 return state_; |
214 } | 208 } |
215 | 209 |
216 syncer::ModelTypeSet BackendMigrator::GetPendingMigrationTypesForTest() const { | 210 ModelTypeSet BackendMigrator::GetPendingMigrationTypesForTest() const { |
217 return to_migrate_; | 211 return to_migrate_; |
218 } | 212 } |
219 | 213 |
220 #undef SDVLOG | 214 #undef SDVLOG |
221 | 215 |
222 #undef SLOG | 216 #undef SLOG |
223 | 217 |
224 }; // namespace browser_sync | 218 }; // namespace browser_sync |
OLD | NEW |