Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: chrome/browser/sync/profile_sync_components_factory_impl.cc

Issue 436733002: [Sync] Use OnSingleDataTypeUnrecoverableError for all errors (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More cleanup Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "base/command_line.h" 5 #include "base/command_line.h"
6 #include "build/build_config.h" 6 #include "build/build_config.h"
7 #include "chrome/browser/bookmarks/bookmark_model_factory.h" 7 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
8 #include "chrome/browser/bookmarks/enhanced_bookmarks_features.h" 8 #include "chrome/browser/bookmarks/enhanced_bookmarks_features.h"
9 #include "chrome/browser/dom_distiller/dom_distiller_service_factory.h" 9 #include "chrome/browser/dom_distiller/dom_distiller_service_factory.h"
10 #include "chrome/browser/history/history_service.h" 10 #include "chrome/browser/history/history_service.h"
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 syncer::ModelTypeSet disabled_types = 172 syncer::ModelTypeSet disabled_types =
173 GetDisabledTypesFromCommandLine(*command_line_); 173 GetDisabledTypesFromCommandLine(*command_line_);
174 syncer::ModelTypeSet enabled_types = 174 syncer::ModelTypeSet enabled_types =
175 GetEnabledTypesFromCommandLine(*command_line_); 175 GetEnabledTypesFromCommandLine(*command_line_);
176 RegisterCommonDataTypes(disabled_types, enabled_types, pss); 176 RegisterCommonDataTypes(disabled_types, enabled_types, pss);
177 #if !defined(OS_ANDROID) 177 #if !defined(OS_ANDROID)
178 RegisterDesktopDataTypes(disabled_types, enabled_types, pss); 178 RegisterDesktopDataTypes(disabled_types, enabled_types, pss);
179 #endif 179 #endif
180 } 180 }
181 181
182 void ProfileSyncComponentsFactoryImpl::DisableBrokenType(
183 syncer::ModelType type,
184 const tracked_objects::Location& from_here,
185 const std::string& message) {
186 ProfileSyncService* p = ProfileSyncServiceFactory::GetForProfile(profile_);
187 syncer::SyncError error(
188 from_here, syncer::SyncError::DATATYPE_ERROR, message, type);
189 p->DisableDatatype(error);
190 }
191
192 DataTypeController::DisableTypeCallback
193 ProfileSyncComponentsFactoryImpl::MakeDisableCallbackFor(
194 syncer::ModelType type) {
195 return base::Bind(&ProfileSyncComponentsFactoryImpl::DisableBrokenType,
196 weak_factory_.GetWeakPtr(),
197 type);
198 }
199
200 void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes( 182 void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
201 syncer::ModelTypeSet disabled_types, 183 syncer::ModelTypeSet disabled_types,
202 syncer::ModelTypeSet enabled_types, 184 syncer::ModelTypeSet enabled_types,
203 ProfileSyncService* pss) { 185 ProfileSyncService* pss) {
204 // Autofill sync is enabled by default. Register unless explicitly 186 // Autofill sync is enabled by default. Register unless explicitly
205 // disabled. 187 // disabled.
206 if (!disabled_types.Has(syncer::AUTOFILL)) { 188 if (!disabled_types.Has(syncer::AUTOFILL)) {
207 pss->RegisterDataTypeController( 189 pss->RegisterDataTypeController(
208 new AutofillDataTypeController( 190 new AutofillDataTypeController(this, profile_));
209 this, profile_, MakeDisableCallbackFor(syncer::AUTOFILL)));
210 } 191 }
211 192
212 // Autofill profile sync is enabled by default. Register unless explicitly 193 // Autofill profile sync is enabled by default. Register unless explicitly
213 // disabled. 194 // disabled.
214 if (!disabled_types.Has(syncer::AUTOFILL_PROFILE)) { 195 if (!disabled_types.Has(syncer::AUTOFILL_PROFILE)) {
215 pss->RegisterDataTypeController( 196 pss->RegisterDataTypeController(
216 new AutofillProfileDataTypeController( 197 new AutofillProfileDataTypeController(this, profile_));
217 this, profile_, MakeDisableCallbackFor(syncer::AUTOFILL_PROFILE)));
218 } 198 }
219 199
220 // Bookmark sync is enabled by default. Register unless explicitly 200 // Bookmark sync is enabled by default. Register unless explicitly
221 // disabled. 201 // disabled.
222 if (!disabled_types.Has(syncer::BOOKMARKS)) { 202 if (!disabled_types.Has(syncer::BOOKMARKS)) {
223 pss->RegisterDataTypeController( 203 pss->RegisterDataTypeController(
224 new BookmarkDataTypeController(this, profile_, pss)); 204 new BookmarkDataTypeController(this, profile_, pss));
225 } 205 }
226 206
227 // TypedUrl sync is enabled by default. Register unless explicitly disabled, 207 // TypedUrl sync is enabled by default. Register unless explicitly disabled,
228 // or if saving history is disabled. 208 // or if saving history is disabled.
229 if (!profile_->GetPrefs()->GetBoolean(prefs::kSavingBrowserHistoryDisabled) && 209 if (!profile_->GetPrefs()->GetBoolean(prefs::kSavingBrowserHistoryDisabled) &&
230 !disabled_types.Has(syncer::TYPED_URLS)) { 210 !disabled_types.Has(syncer::TYPED_URLS)) {
231 pss->RegisterDataTypeController( 211 pss->RegisterDataTypeController(
232 new TypedUrlDataTypeController(this, profile_, pss)); 212 new TypedUrlDataTypeController(this, profile_, pss));
233 } 213 }
234 214
235 // Delete directive sync is enabled by default. Register unless full history 215 // Delete directive sync is enabled by default. Register unless full history
236 // sync is disabled. 216 // sync is disabled.
237 if (!disabled_types.Has(syncer::HISTORY_DELETE_DIRECTIVES)) { 217 if (!disabled_types.Has(syncer::HISTORY_DELETE_DIRECTIVES)) {
238 pss->RegisterDataTypeController( 218 pss->RegisterDataTypeController(
239 new UIDataTypeController( 219 new UIDataTypeController(
240 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 220 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
241 base::Bind(&ChromeReportUnrecoverableError), 221 base::Bind(&ChromeReportUnrecoverableError),
242 MakeDisableCallbackFor(syncer::HISTORY_DELETE_DIRECTIVES),
243 syncer::HISTORY_DELETE_DIRECTIVES, 222 syncer::HISTORY_DELETE_DIRECTIVES,
244 this)); 223 this));
245 } 224 }
246 225
247 // Session sync is enabled by default. Register unless explicitly disabled. 226 // Session sync is enabled by default. Register unless explicitly disabled.
248 if (!disabled_types.Has(syncer::PROXY_TABS)) { 227 if (!disabled_types.Has(syncer::PROXY_TABS)) {
249 pss->RegisterDataTypeController(new ProxyDataTypeController( 228 pss->RegisterDataTypeController(new ProxyDataTypeController(
250 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 229 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
251 syncer::PROXY_TABS)); 230 syncer::PROXY_TABS));
252 pss->RegisterDataTypeController( 231 pss->RegisterDataTypeController(
253 new SessionDataTypeController( 232 new SessionDataTypeController(this,
254 this, 233 profile_,
255 profile_, 234 pss->GetSyncedWindowDelegatesGetter(),
256 pss->GetSyncedWindowDelegatesGetter(), 235 pss->GetLocalDeviceInfoProvider()));
257 pss->GetLocalDeviceInfoProvider(),
258 MakeDisableCallbackFor(syncer::SESSIONS)));
259 } 236 }
260 237
261 // Favicon sync is enabled by default. Register unless explicitly disabled. 238 // Favicon sync is enabled by default. Register unless explicitly disabled.
262 if (!disabled_types.Has(syncer::FAVICON_IMAGES) && 239 if (!disabled_types.Has(syncer::FAVICON_IMAGES) &&
263 !disabled_types.Has(syncer::FAVICON_TRACKING)) { 240 !disabled_types.Has(syncer::FAVICON_TRACKING)) {
264 pss->RegisterDataTypeController( 241 pss->RegisterDataTypeController(
265 new UIDataTypeController( 242 new UIDataTypeController(
266 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 243 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
267 base::Bind(&ChromeReportUnrecoverableError), 244 base::Bind(&ChromeReportUnrecoverableError),
268 MakeDisableCallbackFor(syncer::FAVICON_IMAGES),
269 syncer::FAVICON_IMAGES, 245 syncer::FAVICON_IMAGES,
270 this)); 246 this));
271 pss->RegisterDataTypeController( 247 pss->RegisterDataTypeController(
272 new UIDataTypeController( 248 new UIDataTypeController(
273 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 249 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
274 base::Bind(&ChromeReportUnrecoverableError), 250 base::Bind(&ChromeReportUnrecoverableError),
275 MakeDisableCallbackFor(syncer::FAVICON_TRACKING),
276 syncer::FAVICON_TRACKING, 251 syncer::FAVICON_TRACKING,
277 this)); 252 this));
278 } 253 }
279 254
280 // Password sync is enabled by default. Register unless explicitly 255 // Password sync is enabled by default. Register unless explicitly
281 // disabled. 256 // disabled.
282 if (!disabled_types.Has(syncer::PASSWORDS)) { 257 if (!disabled_types.Has(syncer::PASSWORDS)) {
283 pss->RegisterDataTypeController( 258 pss->RegisterDataTypeController(
284 new PasswordDataTypeController( 259 new PasswordDataTypeController(this, profile_));
285 this, profile_, MakeDisableCallbackFor(syncer::PASSWORDS)));
286 } 260 }
287 261
288 // Article sync is disabled by default. Register only if explicitly enabled. 262 // Article sync is disabled by default. Register only if explicitly enabled.
289 if (IsEnableSyncArticlesSet()) { 263 if (IsEnableSyncArticlesSet()) {
290 pss->RegisterDataTypeController( 264 pss->RegisterDataTypeController(
291 new UIDataTypeController( 265 new UIDataTypeController(
292 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 266 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
293 base::Bind(&ChromeReportUnrecoverableError), 267 base::Bind(&ChromeReportUnrecoverableError),
294 MakeDisableCallbackFor(syncer::ARTICLES),
295 syncer::ARTICLES, 268 syncer::ARTICLES,
296 this)); 269 this));
297 } 270 }
298 271
299 #if defined(ENABLE_MANAGED_USERS) 272 #if defined(ENABLE_MANAGED_USERS)
300 pss->RegisterDataTypeController( 273 pss->RegisterDataTypeController(
301 new SupervisedUserSyncDataTypeController( 274 new SupervisedUserSyncDataTypeController(
302 MakeDisableCallbackFor(syncer::SUPERVISED_USER_SETTINGS),
303 syncer::SUPERVISED_USER_SETTINGS, 275 syncer::SUPERVISED_USER_SETTINGS,
304 this, 276 this,
305 profile_)); 277 profile_));
306 pss->RegisterDataTypeController( 278 pss->RegisterDataTypeController(
307 new SupervisedUserSyncDataTypeController( 279 new SupervisedUserSyncDataTypeController(
308 MakeDisableCallbackFor(syncer::SUPERVISED_USERS),
309 syncer::SUPERVISED_USERS, 280 syncer::SUPERVISED_USERS,
310 this, 281 this,
311 profile_)); 282 profile_));
312 pss->RegisterDataTypeController( 283 pss->RegisterDataTypeController(
313 new SupervisedUserSyncDataTypeController( 284 new SupervisedUserSyncDataTypeController(
314 MakeDisableCallbackFor(syncer::SUPERVISED_USER_SHARED_SETTINGS),
315 syncer::SUPERVISED_USER_SHARED_SETTINGS, 285 syncer::SUPERVISED_USER_SHARED_SETTINGS,
316 this, 286 this,
317 profile_)); 287 profile_));
318 #endif 288 #endif
319 } 289 }
320 290
321 void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes( 291 void ProfileSyncComponentsFactoryImpl::RegisterDesktopDataTypes(
322 syncer::ModelTypeSet disabled_types, 292 syncer::ModelTypeSet disabled_types,
323 syncer::ModelTypeSet enabled_types, 293 syncer::ModelTypeSet enabled_types,
324 ProfileSyncService* pss) { 294 ProfileSyncService* pss) {
325 // App sync is enabled by default. Register unless explicitly 295 // App sync is enabled by default. Register unless explicitly
326 // disabled. 296 // disabled.
327 if (!disabled_types.Has(syncer::APPS)) { 297 if (!disabled_types.Has(syncer::APPS)) {
328 pss->RegisterDataTypeController( 298 pss->RegisterDataTypeController(
329 new ExtensionDataTypeController(syncer::APPS, this, profile_, 299 new ExtensionDataTypeController(syncer::APPS, this, profile_));
330 MakeDisableCallbackFor(syncer::APPS)));
331 } 300 }
332 301
333 // Extension sync is enabled by default. Register unless explicitly 302 // Extension sync is enabled by default. Register unless explicitly
334 // disabled. 303 // disabled.
335 if (!disabled_types.Has(syncer::EXTENSIONS)) { 304 if (!disabled_types.Has(syncer::EXTENSIONS)) {
336 pss->RegisterDataTypeController( 305 pss->RegisterDataTypeController(
337 new ExtensionDataTypeController( 306 new ExtensionDataTypeController(syncer::EXTENSIONS, this, profile_));
338 syncer::EXTENSIONS, this, profile_,
339 MakeDisableCallbackFor(syncer::EXTENSIONS)));
340 } 307 }
341 308
342 // Preference sync is enabled by default. Register unless explicitly 309 // Preference sync is enabled by default. Register unless explicitly
343 // disabled. 310 // disabled.
344 if (!disabled_types.Has(syncer::PREFERENCES)) { 311 if (!disabled_types.Has(syncer::PREFERENCES)) {
345 pss->RegisterDataTypeController( 312 pss->RegisterDataTypeController(
346 new UIDataTypeController( 313 new UIDataTypeController(
347 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 314 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
348 base::Bind(&ChromeReportUnrecoverableError), 315 base::Bind(&ChromeReportUnrecoverableError),
349 MakeDisableCallbackFor(syncer::PREFERENCES),
350 syncer::PREFERENCES, 316 syncer::PREFERENCES,
351 this)); 317 this));
352 } 318 }
353 319
354 if (!disabled_types.Has(syncer::PRIORITY_PREFERENCES)) { 320 if (!disabled_types.Has(syncer::PRIORITY_PREFERENCES)) {
355 pss->RegisterDataTypeController( 321 pss->RegisterDataTypeController(
356 new UIDataTypeController( 322 new UIDataTypeController(
357 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 323 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
358 base::Bind(&ChromeReportUnrecoverableError), 324 base::Bind(&ChromeReportUnrecoverableError),
359 MakeDisableCallbackFor(syncer::PRIORITY_PREFERENCES),
360 syncer::PRIORITY_PREFERENCES, 325 syncer::PRIORITY_PREFERENCES,
361 this)); 326 this));
362 } 327 }
363 328
364 #if defined(ENABLE_THEMES) 329 #if defined(ENABLE_THEMES)
365 // Theme sync is enabled by default. Register unless explicitly disabled. 330 // Theme sync is enabled by default. Register unless explicitly disabled.
366 if (!disabled_types.Has(syncer::THEMES)) { 331 if (!disabled_types.Has(syncer::THEMES)) {
367 pss->RegisterDataTypeController( 332 pss->RegisterDataTypeController(
368 new ThemeDataTypeController(this, profile_, 333 new ThemeDataTypeController(this, profile_));
369 MakeDisableCallbackFor(syncer::THEMES)));
370 } 334 }
371 #endif 335 #endif
372 336
373 // Search Engine sync is enabled by default. Register unless explicitly 337 // Search Engine sync is enabled by default. Register unless explicitly
374 // disabled. 338 // disabled.
375 if (!disabled_types.Has(syncer::SEARCH_ENGINES)) { 339 if (!disabled_types.Has(syncer::SEARCH_ENGINES)) {
376 pss->RegisterDataTypeController( 340 pss->RegisterDataTypeController(
377 new SearchEngineDataTypeController( 341 new SearchEngineDataTypeController(this, profile_));
378 this, profile_, MakeDisableCallbackFor(syncer::SEARCH_ENGINES)));
379 } 342 }
380 343
381 // Extension setting sync is enabled by default. Register unless explicitly 344 // Extension setting sync is enabled by default. Register unless explicitly
382 // disabled. 345 // disabled.
383 if (!disabled_types.Has(syncer::EXTENSION_SETTINGS)) { 346 if (!disabled_types.Has(syncer::EXTENSION_SETTINGS)) {
384 pss->RegisterDataTypeController( 347 pss->RegisterDataTypeController(new ExtensionSettingDataTypeController(
385 new ExtensionSettingDataTypeController( 348 syncer::EXTENSION_SETTINGS, this, profile_));
386 syncer::EXTENSION_SETTINGS, this, profile_,
387 MakeDisableCallbackFor(syncer::EXTENSION_SETTINGS)));
388 } 349 }
389 350
390 // App setting sync is enabled by default. Register unless explicitly 351 // App setting sync is enabled by default. Register unless explicitly
391 // disabled. 352 // disabled.
392 if (!disabled_types.Has(syncer::APP_SETTINGS)) { 353 if (!disabled_types.Has(syncer::APP_SETTINGS)) {
393 pss->RegisterDataTypeController( 354 pss->RegisterDataTypeController(new ExtensionSettingDataTypeController(
394 new ExtensionSettingDataTypeController( 355 syncer::APP_SETTINGS, this, profile_));
395 syncer::APP_SETTINGS, this, profile_,
396 MakeDisableCallbackFor(syncer::APP_SETTINGS)));
397 } 356 }
398 357
399 #if defined(ENABLE_APP_LIST) 358 #if defined(ENABLE_APP_LIST)
400 if (app_list::switches::IsAppListSyncEnabled()) { 359 if (app_list::switches::IsAppListSyncEnabled()) {
401 pss->RegisterDataTypeController( 360 pss->RegisterDataTypeController(
402 new UIDataTypeController( 361 new UIDataTypeController(
403 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 362 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
404 base::Bind(&ChromeReportUnrecoverableError), 363 base::Bind(&ChromeReportUnrecoverableError),
405 MakeDisableCallbackFor(syncer::APP_LIST),
406 syncer::APP_LIST, 364 syncer::APP_LIST,
407 this)); 365 this));
408 } 366 }
409 #endif 367 #endif
410 368
411 // Synced Notifications are disabled by default. 369 // Synced Notifications are disabled by default.
412 #if defined(ENABLE_EXTENSIONS) && defined(ENABLE_NOTIFICATIONS) 370 #if defined(ENABLE_EXTENSIONS) && defined(ENABLE_NOTIFICATIONS)
413 if (enabled_types.Has(syncer::SYNCED_NOTIFICATIONS)) { 371 if (enabled_types.Has(syncer::SYNCED_NOTIFICATIONS)) {
414 pss->RegisterDataTypeController( 372 pss->RegisterDataTypeController(
415 new ExtensionBackedDataTypeController( 373 new ExtensionBackedDataTypeController(
416 MakeDisableCallbackFor(syncer::SYNCED_NOTIFICATIONS),
417 syncer::SYNCED_NOTIFICATIONS, 374 syncer::SYNCED_NOTIFICATIONS,
418 "", // TODO(dewittj): pass the extension hash here. 375 "", // TODO(dewittj): pass the extension hash here.
419 this, 376 this,
420 profile_)); 377 profile_));
421 378
422 pss->RegisterDataTypeController( 379 pss->RegisterDataTypeController(
423 new ExtensionBackedDataTypeController( 380 new ExtensionBackedDataTypeController(
424 MakeDisableCallbackFor(syncer::SYNCED_NOTIFICATION_APP_INFO),
425 syncer::SYNCED_NOTIFICATION_APP_INFO, 381 syncer::SYNCED_NOTIFICATION_APP_INFO,
426 "", // TODO(dewittj): pass the extension hash here. 382 "", // TODO(dewittj): pass the extension hash here.
427 this, 383 this,
428 profile_)); 384 profile_));
429 } 385 }
430 #endif 386 #endif
431 387
432 #if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_CHROMEOS) 388 #if defined(OS_LINUX) || defined(OS_WIN) || defined(OS_CHROMEOS)
433 // Dictionary sync is enabled by default. 389 // Dictionary sync is enabled by default.
434 if (!disabled_types.Has(syncer::DICTIONARY)) { 390 if (!disabled_types.Has(syncer::DICTIONARY)) {
435 pss->RegisterDataTypeController( 391 pss->RegisterDataTypeController(
436 new UIDataTypeController( 392 new UIDataTypeController(
437 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), 393 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
438 base::Bind(&ChromeReportUnrecoverableError), 394 base::Bind(&ChromeReportUnrecoverableError),
439 MakeDisableCallbackFor(syncer::DICTIONARY),
440 syncer::DICTIONARY, 395 syncer::DICTIONARY,
441 this)); 396 this));
442 } 397 }
443 #endif 398 #endif
444 } 399 }
445 400
446 DataTypeManager* ProfileSyncComponentsFactoryImpl::CreateDataTypeManager( 401 DataTypeManager* ProfileSyncComponentsFactoryImpl::CreateDataTypeManager(
447 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& 402 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
448 debug_info_listener, 403 debug_info_listener,
449 const DataTypeController::TypeMap* controllers, 404 const DataTypeController::TypeMap* controllers,
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 new TypedUrlModelAssociator(profile_sync_service, 672 new TypedUrlModelAssociator(profile_sync_service,
718 history_backend, 673 history_backend,
719 error_handler); 674 error_handler);
720 TypedUrlChangeProcessor* change_processor = 675 TypedUrlChangeProcessor* change_processor =
721 new TypedUrlChangeProcessor(profile_, 676 new TypedUrlChangeProcessor(profile_,
722 model_associator, 677 model_associator,
723 history_backend, 678 history_backend,
724 error_handler); 679 error_handler);
725 return SyncComponents(model_associator, change_processor); 680 return SyncComponents(model_associator, change_processor);
726 } 681 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698