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

Side by Side Diff: ppapi/proxy/ppb_flash_proxy.cc

Issue 11299147: Pepper proxy: make the browser sender handle the proxy lock properly. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years 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 "ppapi/proxy/ppb_flash_proxy.h" 5 #include "ppapi/proxy/ppb_flash_proxy.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <limits> 9 #include <limits>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "base/time.h" 13 #include "base/time.h"
14 #include "build/build_config.h" 14 #include "build/build_config.h"
15 #include "ppapi/c/dev/ppb_font_dev.h" 15 #include "ppapi/c/dev/ppb_font_dev.h"
16 #include "ppapi/c/dev/ppb_var_deprecated.h" 16 #include "ppapi/c/dev/ppb_var_deprecated.h"
17 #include "ppapi/c/pp_errors.h" 17 #include "ppapi/c/pp_errors.h"
18 #include "ppapi/c/pp_resource.h" 18 #include "ppapi/c/pp_resource.h"
19 #include "ppapi/c/private/ppb_flash.h" 19 #include "ppapi/c/private/ppb_flash.h"
20 #include "ppapi/c/private/ppb_flash_print.h" 20 #include "ppapi/c/private/ppb_flash_print.h"
21 #include "ppapi/proxy/host_dispatcher.h" 21 #include "ppapi/proxy/host_dispatcher.h"
22 #include "ppapi/proxy/pepper_file_messages.h" 22 #include "ppapi/proxy/pepper_file_messages.h"
23 #include "ppapi/proxy/plugin_dispatcher.h" 23 #include "ppapi/proxy/plugin_dispatcher.h"
24 #include "ppapi/proxy/plugin_globals.h" 24 #include "ppapi/proxy/plugin_globals.h"
25 #include "ppapi/proxy/plugin_proxy_delegate.h"
26 #include "ppapi/proxy/ppapi_messages.h" 25 #include "ppapi/proxy/ppapi_messages.h"
27 #include "ppapi/proxy/proxy_module.h" 26 #include "ppapi/proxy/proxy_module.h"
28 #include "ppapi/proxy/serialized_var.h" 27 #include "ppapi/proxy/serialized_var.h"
29 #include "ppapi/shared_impl/dir_contents.h" 28 #include "ppapi/shared_impl/dir_contents.h"
30 #include "ppapi/shared_impl/file_type_conversion.h" 29 #include "ppapi/shared_impl/file_type_conversion.h"
31 #include "ppapi/shared_impl/ppapi_globals.h" 30 #include "ppapi/shared_impl/ppapi_globals.h"
32 #include "ppapi/shared_impl/proxy_lock.h" 31 #include "ppapi/shared_impl/proxy_lock.h"
33 #include "ppapi/shared_impl/resource.h" 32 #include "ppapi/shared_impl/resource.h"
34 #include "ppapi/shared_impl/resource_tracker.h" 33 #include "ppapi/shared_impl/resource_tracker.h"
35 #include "ppapi/shared_impl/scoped_pp_resource.h" 34 #include "ppapi/shared_impl/scoped_pp_resource.h"
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 277
279 PP_Bool PPB_Flash_Proxy::IsRectTopmost(PP_Instance instance, 278 PP_Bool PPB_Flash_Proxy::IsRectTopmost(PP_Instance instance,
280 const PP_Rect* rect) { 279 const PP_Rect* rect) {
281 PP_Bool result = PP_FALSE; 280 PP_Bool result = PP_FALSE;
282 dispatcher()->Send(new PpapiHostMsg_PPBFlash_IsRectTopmost( 281 dispatcher()->Send(new PpapiHostMsg_PPBFlash_IsRectTopmost(
283 API_ID_PPB_FLASH, instance, *rect, &result)); 282 API_ID_PPB_FLASH, instance, *rect, &result));
284 return result; 283 return result;
285 } 284 }
286 285
287 void PPB_Flash_Proxy::UpdateActivity(PP_Instance instance) { 286 void PPB_Flash_Proxy::UpdateActivity(PP_Instance instance) {
288 PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser( 287 PluginGlobals::Get()->GetBrowserSender()->Send(
289 new PpapiHostMsg_PPBFlash_UpdateActivity(API_ID_PPB_FLASH)); 288 new PpapiHostMsg_PPBFlash_UpdateActivity(API_ID_PPB_FLASH));
290 } 289 }
291 290
292 PP_Var PPB_Flash_Proxy::GetDeviceID(PP_Instance instance) { 291 PP_Var PPB_Flash_Proxy::GetDeviceID(PP_Instance instance) {
293 ReceiveSerializedVarReturnValue result; 292 ReceiveSerializedVarReturnValue result;
294 dispatcher()->Send(new PpapiHostMsg_PPBFlash_GetDeviceID( 293 dispatcher()->Send(new PpapiHostMsg_PPBFlash_GetDeviceID(
295 API_ID_PPB_FLASH, instance, &result)); 294 API_ID_PPB_FLASH, instance, &result));
296 return result.Return(dispatcher()); 295 return result.Return(dispatcher());
297 } 296 }
298 297
(...skipping 23 matching lines...) Expand all
322 case PP_FLASHSETTING_3DENABLED: 321 case PP_FLASHSETTING_3DENABLED:
323 return PP_MakeBool(PP_FromBool( 322 return PP_MakeBool(PP_FromBool(
324 plugin_dispatcher->preferences().is_3d_supported)); 323 plugin_dispatcher->preferences().is_3d_supported));
325 case PP_FLASHSETTING_INCOGNITO: 324 case PP_FLASHSETTING_INCOGNITO:
326 return PP_MakeBool(PP_FromBool(plugin_dispatcher->incognito())); 325 return PP_MakeBool(PP_FromBool(plugin_dispatcher->incognito()));
327 case PP_FLASHSETTING_STAGE3DENABLED: 326 case PP_FLASHSETTING_STAGE3DENABLED:
328 return PP_MakeBool(PP_FromBool( 327 return PP_MakeBool(PP_FromBool(
329 plugin_dispatcher->preferences().is_stage3d_supported)); 328 plugin_dispatcher->preferences().is_stage3d_supported));
330 case PP_FLASHSETTING_LANGUAGE: 329 case PP_FLASHSETTING_LANGUAGE:
331 return StringVar::StringToPPVar( 330 return StringVar::StringToPPVar(
332 PluginGlobals::Get()->plugin_proxy_delegate()->GetUILanguage()); 331 PluginGlobals::Get()->GetUILanguage());
333 case PP_FLASHSETTING_NUMCORES: 332 case PP_FLASHSETTING_NUMCORES:
334 return PP_MakeInt32(plugin_dispatcher->preferences().number_of_cpu_cores); 333 return PP_MakeInt32(plugin_dispatcher->preferences().number_of_cpu_cores);
335 case PP_FLASHSETTING_LSORESTRICTIONS: { 334 case PP_FLASHSETTING_LSORESTRICTIONS: {
336 ReceiveSerializedVarReturnValue result; 335 ReceiveSerializedVarReturnValue result;
337 dispatcher()->Send(new PpapiHostMsg_PPBFlash_GetSetting( 336 dispatcher()->Send(new PpapiHostMsg_PPBFlash_GetSetting(
338 API_ID_PPB_FLASH, instance, setting, &result)); 337 API_ID_PPB_FLASH, instance, setting, &result));
339 return result.Return(dispatcher()); 338 return result.Return(dispatcher());
340 } 339 }
341 } 340 }
342 return PP_MakeUndefined(); 341 return PP_MakeUndefined();
343 } 342 }
344 343
345 PP_Bool PPB_Flash_Proxy::SetCrashData(PP_Instance instance, 344 PP_Bool PPB_Flash_Proxy::SetCrashData(PP_Instance instance,
346 PP_FlashCrashKey key, 345 PP_FlashCrashKey key,
347 PP_Var value) { 346 PP_Var value) {
348 switch (key) { 347 switch (key) {
349 case PP_FLASHCRASHKEY_URL: 348 case PP_FLASHCRASHKEY_URL:
350 StringVar *url_string_var(StringVar::FromPPVar(value)); 349 StringVar *url_string_var(StringVar::FromPPVar(value));
351 if (!url_string_var) 350 if (!url_string_var)
352 return PP_FALSE; 351 return PP_FALSE;
353 std::string url_string(url_string_var->value()); 352 std::string url_string(url_string_var->value());
354 PluginGlobals::Get()->plugin_proxy_delegate()->SetActiveURL(url_string); 353 PluginGlobals::Get()->SetActiveURL(url_string);
355 return PP_TRUE; 354 return PP_TRUE;
356 } 355 }
357 return PP_FALSE; 356 return PP_FALSE;
358 } 357 }
359 358
360 bool PPB_Flash_Proxy::CreateThreadAdapterForInstance(PP_Instance instance) { 359 bool PPB_Flash_Proxy::CreateThreadAdapterForInstance(PP_Instance instance) {
361 return true; 360 return true;
362 } 361 }
363 362
364 void PPB_Flash_Proxy::ClearThreadAdapterForInstance(PP_Instance instance) { 363 void PPB_Flash_Proxy::ClearThreadAdapterForInstance(PP_Instance instance) {
365 } 364 }
366 365
367 int32_t PPB_Flash_Proxy::OpenFile(PP_Instance, 366 int32_t PPB_Flash_Proxy::OpenFile(PP_Instance,
368 const char* path, 367 const char* path,
369 int32_t mode, 368 int32_t mode,
370 PP_FileHandle* file) { 369 PP_FileHandle* file) {
371 int flags = 0; 370 int flags = 0;
372 if (!path || 371 if (!path ||
373 !ppapi::PepperFileOpenFlagsToPlatformFileFlags(mode, &flags) || 372 !ppapi::PepperFileOpenFlagsToPlatformFileFlags(mode, &flags) ||
374 !file) 373 !file)
375 return PP_ERROR_BADARGUMENT; 374 return PP_ERROR_BADARGUMENT;
376 375
377 base::PlatformFileError error; 376 base::PlatformFileError error;
378 IPC::PlatformFileForTransit transit_file; 377 IPC::PlatformFileForTransit transit_file;
379 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, 378 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL,
380 FilePath::FromUTF8Unsafe(path)); 379 FilePath::FromUTF8Unsafe(path));
381 380
382 if (PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser( 381 if (PluginGlobals::Get()->GetBrowserSender()->Send(
383 new PepperFileMsg_OpenFile(pepper_path, flags, 382 new PepperFileMsg_OpenFile(pepper_path, flags,
384 &error, &transit_file))) { 383 &error, &transit_file))) {
385 *file = IPC::PlatformFileForTransitToPlatformFile(transit_file); 384 *file = IPC::PlatformFileForTransitToPlatformFile(transit_file);
386 } else { 385 } else {
387 *file = base::kInvalidPlatformFileValue; 386 *file = base::kInvalidPlatformFileValue;
388 error = base::PLATFORM_FILE_ERROR_FAILED; 387 error = base::PLATFORM_FILE_ERROR_FAILED;
389 } 388 }
390 389
391 return ppapi::PlatformFileErrorToPepperError(error); 390 return ppapi::PlatformFileErrorToPepperError(error);
392 } 391 }
393 392
394 int32_t PPB_Flash_Proxy::RenameFile(PP_Instance, 393 int32_t PPB_Flash_Proxy::RenameFile(PP_Instance,
395 const char* from_path, 394 const char* from_path,
396 const char* to_path) { 395 const char* to_path) {
397 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; 396 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED;
398 ppapi::PepperFilePath pepper_from(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, 397 ppapi::PepperFilePath pepper_from(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL,
399 FilePath::FromUTF8Unsafe(from_path)); 398 FilePath::FromUTF8Unsafe(from_path));
400 ppapi::PepperFilePath pepper_to(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, 399 ppapi::PepperFilePath pepper_to(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL,
401 FilePath::FromUTF8Unsafe(to_path)); 400 FilePath::FromUTF8Unsafe(to_path));
402 401
403 PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser( 402 PluginGlobals::Get()->GetBrowserSender()->Send(
404 new PepperFileMsg_RenameFile(pepper_from, pepper_to, &error)); 403 new PepperFileMsg_RenameFile(pepper_from, pepper_to, &error));
405 404
406 return ppapi::PlatformFileErrorToPepperError(error); 405 return ppapi::PlatformFileErrorToPepperError(error);
407 } 406 }
408 407
409 int32_t PPB_Flash_Proxy::DeleteFileOrDir(PP_Instance, 408 int32_t PPB_Flash_Proxy::DeleteFileOrDir(PP_Instance,
410 const char* path, 409 const char* path,
411 PP_Bool recursive) { 410 PP_Bool recursive) {
412 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; 411 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED;
413 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, 412 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL,
414 FilePath::FromUTF8Unsafe(path)); 413 FilePath::FromUTF8Unsafe(path));
415 414
416 PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser( 415 PluginGlobals::Get()->GetBrowserSender()->Send(
417 new PepperFileMsg_DeleteFileOrDir(pepper_path, 416 new PepperFileMsg_DeleteFileOrDir(pepper_path,
418 PP_ToBool(recursive), 417 PP_ToBool(recursive),
419 &error)); 418 &error));
420 419
421 return ppapi::PlatformFileErrorToPepperError(error); 420 return ppapi::PlatformFileErrorToPepperError(error);
422 } 421 }
423 422
424 int32_t PPB_Flash_Proxy::CreateDir(PP_Instance, const char* path) { 423 int32_t PPB_Flash_Proxy::CreateDir(PP_Instance, const char* path) {
425 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; 424 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED;
426 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, 425 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL,
427 FilePath::FromUTF8Unsafe(path)); 426 FilePath::FromUTF8Unsafe(path));
428 427
429 PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser( 428 PluginGlobals::Get()->GetBrowserSender()->Send(
430 new PepperFileMsg_CreateDir(pepper_path, &error)); 429 new PepperFileMsg_CreateDir(pepper_path, &error));
431 430
432 return ppapi::PlatformFileErrorToPepperError(error); 431 return ppapi::PlatformFileErrorToPepperError(error);
433 } 432 }
434 433
435 int32_t PPB_Flash_Proxy::QueryFile(PP_Instance, 434 int32_t PPB_Flash_Proxy::QueryFile(PP_Instance,
436 const char* path, 435 const char* path,
437 PP_FileInfo* info) { 436 PP_FileInfo* info) {
438 base::PlatformFileInfo file_info; 437 base::PlatformFileInfo file_info;
439 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; 438 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED;
440 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, 439 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL,
441 FilePath::FromUTF8Unsafe(path)); 440 FilePath::FromUTF8Unsafe(path));
442 441
443 PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser( 442 PluginGlobals::Get()->GetBrowserSender()->Send(
444 new PepperFileMsg_QueryFile(pepper_path, &file_info, &error)); 443 new PepperFileMsg_QueryFile(pepper_path, &file_info, &error));
445 444
446 if (error == base::PLATFORM_FILE_OK) { 445 if (error == base::PLATFORM_FILE_OK) {
447 info->size = file_info.size; 446 info->size = file_info.size;
448 info->creation_time = TimeToPPTime(file_info.creation_time); 447 info->creation_time = TimeToPPTime(file_info.creation_time);
449 info->last_access_time = TimeToPPTime(file_info.last_accessed); 448 info->last_access_time = TimeToPPTime(file_info.last_accessed);
450 info->last_modified_time = TimeToPPTime(file_info.last_modified); 449 info->last_modified_time = TimeToPPTime(file_info.last_modified);
451 info->system_type = PP_FILESYSTEMTYPE_EXTERNAL; 450 info->system_type = PP_FILESYSTEMTYPE_EXTERNAL;
452 if (file_info.is_directory) 451 if (file_info.is_directory)
453 info->type = PP_FILETYPE_DIRECTORY; 452 info->type = PP_FILETYPE_DIRECTORY;
454 else 453 else
455 info->type = PP_FILETYPE_REGULAR; 454 info->type = PP_FILETYPE_REGULAR;
456 } 455 }
457 456
458 return ppapi::PlatformFileErrorToPepperError(error); 457 return ppapi::PlatformFileErrorToPepperError(error);
459 } 458 }
460 459
461 int32_t PPB_Flash_Proxy::GetDirContents(PP_Instance, 460 int32_t PPB_Flash_Proxy::GetDirContents(PP_Instance,
462 const char* path, 461 const char* path,
463 PP_DirContents_Dev** contents) { 462 PP_DirContents_Dev** contents) {
464 ppapi::DirContents entries; 463 ppapi::DirContents entries;
465 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; 464 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED;
466 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, 465 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL,
467 FilePath::FromUTF8Unsafe(path)); 466 FilePath::FromUTF8Unsafe(path));
468 467
469 PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser( 468 PluginGlobals::Get()->GetBrowserSender()->Send(
470 new PepperFileMsg_GetDirContents(pepper_path, &entries, &error)); 469 new PepperFileMsg_GetDirContents(pepper_path, &entries, &error));
471 470
472 if (error == base::PLATFORM_FILE_OK) { 471 if (error == base::PLATFORM_FILE_OK) {
473 // Copy the serialized dir entries to the output struct. 472 // Copy the serialized dir entries to the output struct.
474 *contents = new PP_DirContents_Dev; 473 *contents = new PP_DirContents_Dev;
475 (*contents)->count = static_cast<int32_t>(entries.size()); 474 (*contents)->count = static_cast<int32_t>(entries.size());
476 (*contents)->entries = new PP_DirEntry_Dev[entries.size()]; 475 (*contents)->entries = new PP_DirEntry_Dev[entries.size()];
477 for (size_t i = 0; i < entries.size(); i++) { 476 for (size_t i = 0; i < entries.size(); i++) {
478 const ppapi::DirEntry& source = entries[i]; 477 const ppapi::DirEntry& source = entries[i];
479 PP_DirEntry_Dev* dest = &(*contents)->entries[i]; 478 PP_DirEntry_Dev* dest = &(*contents)->entries[i];
480 std::string name = source.name.AsUTF8Unsafe(); 479 std::string name = source.name.AsUTF8Unsafe();
481 char* name_copy = new char[name.size() + 1]; 480 char* name_copy = new char[name.size() + 1];
482 memcpy(name_copy, name.c_str(), name.size() + 1); 481 memcpy(name_copy, name.c_str(), name.size() + 1);
483 dest->name = name_copy; 482 dest->name = name_copy;
484 dest->is_dir = PP_FromBool(source.is_dir); 483 dest->is_dir = PP_FromBool(source.is_dir);
485 } 484 }
486 } 485 }
487 486
488 return ppapi::PlatformFileErrorToPepperError(error); 487 return ppapi::PlatformFileErrorToPepperError(error);
489 } 488 }
490 489
491 int32_t PPB_Flash_Proxy::CreateTemporaryFile(PP_Instance instance, 490 int32_t PPB_Flash_Proxy::CreateTemporaryFile(PP_Instance instance,
492 PP_FileHandle* file) { 491 PP_FileHandle* file) {
493 if (!file) 492 if (!file)
494 return PP_ERROR_BADARGUMENT; 493 return PP_ERROR_BADARGUMENT;
495 494
496 base::PlatformFileError error; 495 base::PlatformFileError error;
497 IPC::PlatformFileForTransit transit_file; 496 IPC::PlatformFileForTransit transit_file;
498 497
499 if (PluginGlobals::Get()->plugin_proxy_delegate()->SendToBrowser( 498 if (PluginGlobals::Get()->GetBrowserSender()->Send(
500 new PepperFileMsg_CreateTemporaryFile(&error, &transit_file))) { 499 new PepperFileMsg_CreateTemporaryFile(&error, &transit_file))) {
501 *file = IPC::PlatformFileForTransitToPlatformFile(transit_file); 500 *file = IPC::PlatformFileForTransitToPlatformFile(transit_file);
502 } else { 501 } else {
503 error = base::PLATFORM_FILE_ERROR_FAILED; 502 error = base::PLATFORM_FILE_ERROR_FAILED;
504 *file = base::kInvalidPlatformFileValue; 503 *file = base::kInvalidPlatformFileValue;
505 } 504 }
506 505
507 return ppapi::PlatformFileErrorToPepperError(error); 506 return ppapi::PlatformFileErrorToPepperError(error);
508 } 507 }
509 508
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 // It's rarely used enough that we just request this interface when needed. 764 // It's rarely used enough that we just request this interface when needed.
766 const PPB_Flash_Print_1_0* print_interface = 765 const PPB_Flash_Print_1_0* print_interface =
767 static_cast<const PPB_Flash_Print_1_0*>( 766 static_cast<const PPB_Flash_Print_1_0*>(
768 dispatcher()->local_get_interface()(PPB_FLASH_PRINT_INTERFACE_1_0)); 767 dispatcher()->local_get_interface()(PPB_FLASH_PRINT_INTERFACE_1_0));
769 if (print_interface) 768 if (print_interface)
770 print_interface->InvokePrinting(instance); 769 print_interface->InvokePrinting(instance);
771 } 770 }
772 771
773 } // namespace proxy 772 } // namespace proxy
774 } // namespace ppapi 773 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698