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 "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/containers/mru_cache.h" | 11 #include "base/containers/mru_cache.h" |
12 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
15 #include "base/time.h" | 15 #include "base/time.h" |
16 #include "build/build_config.h" | 16 #include "build/build_config.h" |
17 #include "ppapi/c/dev/ppb_var_deprecated.h" | 17 #include "ppapi/c/dev/ppb_var_deprecated.h" |
18 #include "ppapi/c/pp_errors.h" | 18 #include "ppapi/c/pp_errors.h" |
19 #include "ppapi/c/pp_resource.h" | 19 #include "ppapi/c/pp_resource.h" |
20 #include "ppapi/c/private/ppb_flash.h" | 20 #include "ppapi/c/private/ppb_flash.h" |
21 #include "ppapi/c/private/ppb_flash_print.h" | 21 #include "ppapi/c/private/ppb_flash_print.h" |
22 #include "ppapi/c/trusted/ppb_browser_font_trusted.h" | 22 #include "ppapi/c/trusted/ppb_browser_font_trusted.h" |
23 #include "ppapi/proxy/host_dispatcher.h" | 23 #include "ppapi/proxy/host_dispatcher.h" |
24 #include "ppapi/proxy/pepper_file_messages.h" | |
25 #include "ppapi/proxy/plugin_dispatcher.h" | 24 #include "ppapi/proxy/plugin_dispatcher.h" |
26 #include "ppapi/proxy/plugin_globals.h" | 25 #include "ppapi/proxy/plugin_globals.h" |
27 #include "ppapi/proxy/ppapi_messages.h" | 26 #include "ppapi/proxy/ppapi_messages.h" |
28 #include "ppapi/proxy/proxy_module.h" | 27 #include "ppapi/proxy/proxy_module.h" |
29 #include "ppapi/proxy/serialized_var.h" | 28 #include "ppapi/proxy/serialized_var.h" |
30 #include "ppapi/shared_impl/dir_contents.h" | |
31 #include "ppapi/shared_impl/file_type_conversion.h" | |
32 #include "ppapi/shared_impl/ppapi_globals.h" | 29 #include "ppapi/shared_impl/ppapi_globals.h" |
33 #include "ppapi/shared_impl/proxy_lock.h" | 30 #include "ppapi/shared_impl/proxy_lock.h" |
34 #include "ppapi/shared_impl/resource.h" | 31 #include "ppapi/shared_impl/resource.h" |
35 #include "ppapi/shared_impl/resource_tracker.h" | 32 #include "ppapi/shared_impl/resource_tracker.h" |
36 #include "ppapi/shared_impl/scoped_pp_resource.h" | 33 #include "ppapi/shared_impl/scoped_pp_resource.h" |
37 #include "ppapi/shared_impl/time_conversion.h" | 34 #include "ppapi/shared_impl/time_conversion.h" |
38 #include "ppapi/shared_impl/var.h" | 35 #include "ppapi/shared_impl/var.h" |
39 #include "ppapi/shared_impl/var_tracker.h" | 36 #include "ppapi/shared_impl/var_tracker.h" |
40 #include "ppapi/thunk/enter.h" | 37 #include "ppapi/thunk/enter.h" |
41 #include "ppapi/thunk/ppb_instance_api.h" | 38 #include "ppapi/thunk/ppb_instance_api.h" |
(...skipping 18 matching lines...) Expand all Loading... |
60 public: | 57 public: |
61 LocalTimeZoneOffsetCache() | 58 LocalTimeZoneOffsetCache() |
62 : base::MRUCache<PP_Time, LocalTimeZoneOffsetEntry>(kCacheSize) {} | 59 : base::MRUCache<PP_Time, LocalTimeZoneOffsetEntry>(kCacheSize) {} |
63 private: | 60 private: |
64 static const size_t kCacheSize = 100; | 61 static const size_t kCacheSize = 100; |
65 }; | 62 }; |
66 | 63 |
67 base::LazyInstance<LocalTimeZoneOffsetCache>::Leaky | 64 base::LazyInstance<LocalTimeZoneOffsetCache>::Leaky |
68 g_local_time_zone_offset_cache = LAZY_INSTANCE_INITIALIZER; | 65 g_local_time_zone_offset_cache = LAZY_INSTANCE_INITIALIZER; |
69 | 66 |
70 IPC::PlatformFileForTransit PlatformFileToPlatformFileForTransit( | |
71 Dispatcher* dispatcher, | |
72 int32_t* error, | |
73 base::PlatformFile file) { | |
74 if (*error != PP_OK) | |
75 return IPC::InvalidPlatformFileForTransit(); | |
76 IPC::PlatformFileForTransit out_handle = | |
77 dispatcher->ShareHandleWithRemote(file, true); | |
78 if (out_handle == IPC::InvalidPlatformFileForTransit()) | |
79 *error = PP_ERROR_NOACCESS; | |
80 return out_handle; | |
81 } | |
82 | |
83 void InvokePrinting(PP_Instance instance) { | 67 void InvokePrinting(PP_Instance instance) { |
84 ProxyAutoLock lock; | 68 ProxyAutoLock lock; |
85 | 69 |
86 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | 70 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); |
87 if (dispatcher) { | 71 if (dispatcher) { |
88 dispatcher->Send(new PpapiHostMsg_PPBFlash_InvokePrinting( | 72 dispatcher->Send(new PpapiHostMsg_PPBFlash_InvokePrinting( |
89 API_ID_PPB_FLASH, instance)); | 73 API_ID_PPB_FLASH, instance)); |
90 } | 74 } |
91 } | 75 } |
92 | 76 |
(...skipping 25 matching lines...) Expand all Loading... |
118 IPC_BEGIN_MESSAGE_MAP(PPB_Flash_Proxy, msg) | 102 IPC_BEGIN_MESSAGE_MAP(PPB_Flash_Proxy, msg) |
119 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_SetInstanceAlwaysOnTop, | 103 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_SetInstanceAlwaysOnTop, |
120 OnHostMsgSetInstanceAlwaysOnTop) | 104 OnHostMsgSetInstanceAlwaysOnTop) |
121 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_DrawGlyphs, | 105 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_DrawGlyphs, |
122 OnHostMsgDrawGlyphs) | 106 OnHostMsgDrawGlyphs) |
123 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_Navigate, OnHostMsgNavigate) | 107 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_Navigate, OnHostMsgNavigate) |
124 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_GetLocalTimeZoneOffset, | 108 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_GetLocalTimeZoneOffset, |
125 OnHostMsgGetLocalTimeZoneOffset) | 109 OnHostMsgGetLocalTimeZoneOffset) |
126 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_IsRectTopmost, | 110 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_IsRectTopmost, |
127 OnHostMsgIsRectTopmost) | 111 OnHostMsgIsRectTopmost) |
128 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_OpenFileRef, | |
129 OnHostMsgOpenFileRef) | |
130 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_QueryFileRef, | |
131 OnHostMsgQueryFileRef) | |
132 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_InvokePrinting, | 112 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_InvokePrinting, |
133 OnHostMsgInvokePrinting) | 113 OnHostMsgInvokePrinting) |
134 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_GetSetting, | 114 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_GetSetting, |
135 OnHostMsgGetSetting) | 115 OnHostMsgGetSetting) |
136 IPC_MESSAGE_UNHANDLED(handled = false) | 116 IPC_MESSAGE_UNHANDLED(handled = false) |
137 IPC_END_MESSAGE_MAP() | 117 IPC_END_MESSAGE_MAP() |
138 // TODO(brettw) handle bad messages! | 118 // TODO(brettw) handle bad messages! |
139 return handled; | 119 return handled; |
140 } | 120 } |
141 | 121 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 case PP_FLASHSETTING_LSORESTRICTIONS: { | 273 case PP_FLASHSETTING_LSORESTRICTIONS: { |
294 ReceiveSerializedVarReturnValue result; | 274 ReceiveSerializedVarReturnValue result; |
295 dispatcher()->Send(new PpapiHostMsg_PPBFlash_GetSetting( | 275 dispatcher()->Send(new PpapiHostMsg_PPBFlash_GetSetting( |
296 API_ID_PPB_FLASH, instance, setting, &result)); | 276 API_ID_PPB_FLASH, instance, setting, &result)); |
297 return result.Return(dispatcher()); | 277 return result.Return(dispatcher()); |
298 } | 278 } |
299 } | 279 } |
300 return PP_MakeUndefined(); | 280 return PP_MakeUndefined(); |
301 } | 281 } |
302 | 282 |
303 bool PPB_Flash_Proxy::CreateThreadAdapterForInstance(PP_Instance instance) { | |
304 return true; | |
305 } | |
306 | |
307 void PPB_Flash_Proxy::ClearThreadAdapterForInstance(PP_Instance instance) { | |
308 } | |
309 | |
310 int32_t PPB_Flash_Proxy::OpenFile(PP_Instance, | |
311 const char* path, | |
312 int32_t mode, | |
313 PP_FileHandle* file) { | |
314 int flags = 0; | |
315 if (!path || | |
316 !ppapi::PepperFileOpenFlagsToPlatformFileFlags(mode, &flags) || | |
317 !file) | |
318 return PP_ERROR_BADARGUMENT; | |
319 | |
320 base::PlatformFileError error; | |
321 IPC::PlatformFileForTransit transit_file; | |
322 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, | |
323 FilePath::FromUTF8Unsafe(path)); | |
324 | |
325 if (PluginGlobals::Get()->GetBrowserSender()->Send( | |
326 new PepperFileMsg_OpenFile(pepper_path, flags, | |
327 &error, &transit_file))) { | |
328 *file = IPC::PlatformFileForTransitToPlatformFile(transit_file); | |
329 } else { | |
330 *file = base::kInvalidPlatformFileValue; | |
331 error = base::PLATFORM_FILE_ERROR_FAILED; | |
332 } | |
333 | |
334 return ppapi::PlatformFileErrorToPepperError(error); | |
335 } | |
336 | |
337 int32_t PPB_Flash_Proxy::RenameFile(PP_Instance, | |
338 const char* from_path, | |
339 const char* to_path) { | |
340 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; | |
341 ppapi::PepperFilePath pepper_from(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, | |
342 FilePath::FromUTF8Unsafe(from_path)); | |
343 ppapi::PepperFilePath pepper_to(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, | |
344 FilePath::FromUTF8Unsafe(to_path)); | |
345 | |
346 PluginGlobals::Get()->GetBrowserSender()->Send( | |
347 new PepperFileMsg_RenameFile(pepper_from, pepper_to, &error)); | |
348 | |
349 return ppapi::PlatformFileErrorToPepperError(error); | |
350 } | |
351 | |
352 int32_t PPB_Flash_Proxy::DeleteFileOrDir(PP_Instance, | |
353 const char* path, | |
354 PP_Bool recursive) { | |
355 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; | |
356 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, | |
357 FilePath::FromUTF8Unsafe(path)); | |
358 | |
359 PluginGlobals::Get()->GetBrowserSender()->Send( | |
360 new PepperFileMsg_DeleteFileOrDir(pepper_path, | |
361 PP_ToBool(recursive), | |
362 &error)); | |
363 | |
364 return ppapi::PlatformFileErrorToPepperError(error); | |
365 } | |
366 | |
367 int32_t PPB_Flash_Proxy::CreateDir(PP_Instance, const char* path) { | |
368 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; | |
369 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, | |
370 FilePath::FromUTF8Unsafe(path)); | |
371 | |
372 PluginGlobals::Get()->GetBrowserSender()->Send( | |
373 new PepperFileMsg_CreateDir(pepper_path, &error)); | |
374 | |
375 return ppapi::PlatformFileErrorToPepperError(error); | |
376 } | |
377 | |
378 int32_t PPB_Flash_Proxy::QueryFile(PP_Instance, | |
379 const char* path, | |
380 PP_FileInfo* info) { | |
381 base::PlatformFileInfo file_info; | |
382 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; | |
383 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, | |
384 FilePath::FromUTF8Unsafe(path)); | |
385 | |
386 PluginGlobals::Get()->GetBrowserSender()->Send( | |
387 new PepperFileMsg_QueryFile(pepper_path, &file_info, &error)); | |
388 | |
389 if (error == base::PLATFORM_FILE_OK) { | |
390 info->size = file_info.size; | |
391 info->creation_time = TimeToPPTime(file_info.creation_time); | |
392 info->last_access_time = TimeToPPTime(file_info.last_accessed); | |
393 info->last_modified_time = TimeToPPTime(file_info.last_modified); | |
394 info->system_type = PP_FILESYSTEMTYPE_EXTERNAL; | |
395 if (file_info.is_directory) | |
396 info->type = PP_FILETYPE_DIRECTORY; | |
397 else | |
398 info->type = PP_FILETYPE_REGULAR; | |
399 } | |
400 | |
401 return ppapi::PlatformFileErrorToPepperError(error); | |
402 } | |
403 | |
404 int32_t PPB_Flash_Proxy::GetDirContents(PP_Instance, | |
405 const char* path, | |
406 PP_DirContents_Dev** contents) { | |
407 ppapi::DirContents entries; | |
408 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED; | |
409 ppapi::PepperFilePath pepper_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, | |
410 FilePath::FromUTF8Unsafe(path)); | |
411 | |
412 PluginGlobals::Get()->GetBrowserSender()->Send( | |
413 new PepperFileMsg_GetDirContents(pepper_path, &entries, &error)); | |
414 | |
415 if (error == base::PLATFORM_FILE_OK) { | |
416 // Copy the serialized dir entries to the output struct. | |
417 *contents = new PP_DirContents_Dev; | |
418 (*contents)->count = static_cast<int32_t>(entries.size()); | |
419 (*contents)->entries = new PP_DirEntry_Dev[entries.size()]; | |
420 for (size_t i = 0; i < entries.size(); i++) { | |
421 const ppapi::DirEntry& source = entries[i]; | |
422 PP_DirEntry_Dev* dest = &(*contents)->entries[i]; | |
423 std::string name = source.name.AsUTF8Unsafe(); | |
424 char* name_copy = new char[name.size() + 1]; | |
425 memcpy(name_copy, name.c_str(), name.size() + 1); | |
426 dest->name = name_copy; | |
427 dest->is_dir = PP_FromBool(source.is_dir); | |
428 } | |
429 } | |
430 | |
431 return ppapi::PlatformFileErrorToPepperError(error); | |
432 } | |
433 | |
434 int32_t PPB_Flash_Proxy::CreateTemporaryFile(PP_Instance instance, | |
435 PP_FileHandle* file) { | |
436 if (!file) | |
437 return PP_ERROR_BADARGUMENT; | |
438 | |
439 base::PlatformFileError error; | |
440 IPC::PlatformFileForTransit transit_file; | |
441 | |
442 if (PluginGlobals::Get()->GetBrowserSender()->Send( | |
443 new PepperFileMsg_CreateTemporaryFile(&error, &transit_file))) { | |
444 *file = IPC::PlatformFileForTransitToPlatformFile(transit_file); | |
445 } else { | |
446 error = base::PLATFORM_FILE_ERROR_FAILED; | |
447 *file = base::kInvalidPlatformFileValue; | |
448 } | |
449 | |
450 return ppapi::PlatformFileErrorToPepperError(error); | |
451 } | |
452 | |
453 int32_t PPB_Flash_Proxy::OpenFileRef(PP_Instance instance, | |
454 PP_Resource file_ref_id, | |
455 int32_t mode, | |
456 PP_FileHandle* file) { | |
457 EnterResourceNoLock<thunk::PPB_FileRef_API> enter(file_ref_id, true); | |
458 if (enter.failed()) | |
459 return PP_ERROR_BADRESOURCE; | |
460 | |
461 int32_t result = PP_ERROR_FAILED; | |
462 IPC::PlatformFileForTransit transit; | |
463 dispatcher()->Send(new PpapiHostMsg_PPBFlash_OpenFileRef( | |
464 API_ID_PPB_FLASH, instance, enter.resource()->host_resource(), mode, | |
465 &transit, &result)); | |
466 *file = IPC::PlatformFileForTransitToPlatformFile(transit); | |
467 return result; | |
468 } | |
469 | |
470 int32_t PPB_Flash_Proxy::QueryFileRef(PP_Instance instance, | |
471 PP_Resource file_ref_id, | |
472 PP_FileInfo* info) { | |
473 EnterResourceNoLock<thunk::PPB_FileRef_API> enter(file_ref_id, true); | |
474 if (enter.failed()) | |
475 return PP_ERROR_BADRESOURCE; | |
476 | |
477 int32_t result = PP_ERROR_FAILED; | |
478 dispatcher()->Send(new PpapiHostMsg_PPBFlash_QueryFileRef( | |
479 API_ID_PPB_FLASH, instance, enter.resource()->host_resource(), info, | |
480 &result)); | |
481 return result; | |
482 } | |
483 | |
484 void PPB_Flash_Proxy::OnHostMsgSetInstanceAlwaysOnTop(PP_Instance instance, | 283 void PPB_Flash_Proxy::OnHostMsgSetInstanceAlwaysOnTop(PP_Instance instance, |
485 PP_Bool on_top) { | 284 PP_Bool on_top) { |
486 EnterInstanceNoLock enter(instance); | 285 EnterInstanceNoLock enter(instance); |
487 if (enter.succeeded()) | 286 if (enter.succeeded()) |
488 enter.functions()->GetFlashAPI()->SetInstanceAlwaysOnTop(instance, on_top); | 287 enter.functions()->GetFlashAPI()->SetInstanceAlwaysOnTop(instance, on_top); |
489 } | 288 } |
490 | 289 |
491 void PPB_Flash_Proxy::OnHostMsgDrawGlyphs( | 290 void PPB_Flash_Proxy::OnHostMsgDrawGlyphs( |
492 PP_Instance instance, | 291 PP_Instance instance, |
493 const PPBFlash_DrawGlyphs_Params& params, | 292 const PPBFlash_DrawGlyphs_Params& params, |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 void PPB_Flash_Proxy::OnHostMsgIsRectTopmost(PP_Instance instance, | 363 void PPB_Flash_Proxy::OnHostMsgIsRectTopmost(PP_Instance instance, |
565 PP_Rect rect, | 364 PP_Rect rect, |
566 PP_Bool* result) { | 365 PP_Bool* result) { |
567 EnterInstanceNoLock enter(instance); | 366 EnterInstanceNoLock enter(instance); |
568 if (enter.succeeded()) | 367 if (enter.succeeded()) |
569 *result = enter.functions()->GetFlashAPI()->IsRectTopmost(instance, &rect); | 368 *result = enter.functions()->GetFlashAPI()->IsRectTopmost(instance, &rect); |
570 else | 369 else |
571 *result = PP_FALSE; | 370 *result = PP_FALSE; |
572 } | 371 } |
573 | 372 |
574 void PPB_Flash_Proxy::OnHostMsgOpenFileRef( | |
575 PP_Instance instance, | |
576 const HostResource& host_resource, | |
577 int32_t mode, | |
578 IPC::PlatformFileForTransit* file_handle, | |
579 int32_t* result) { | |
580 EnterInstanceNoLock enter(instance); | |
581 if (enter.failed()) { | |
582 *result = PP_ERROR_BADARGUMENT; | |
583 return; | |
584 } | |
585 | |
586 base::PlatformFile file; | |
587 *result = enter.functions()->GetFlashAPI()->OpenFileRef( | |
588 instance, host_resource.host_resource(), mode, &file); | |
589 *file_handle = PlatformFileToPlatformFileForTransit(dispatcher(), | |
590 result, file); | |
591 } | |
592 | |
593 void PPB_Flash_Proxy::OnHostMsgQueryFileRef( | |
594 PP_Instance instance, | |
595 const HostResource& host_resource, | |
596 PP_FileInfo* info, | |
597 int32_t* result) { | |
598 EnterInstanceNoLock enter(instance); | |
599 if (enter.failed()) { | |
600 *result = PP_ERROR_BADARGUMENT; | |
601 return; | |
602 } | |
603 *result = enter.functions()->GetFlashAPI()->QueryFileRef( | |
604 instance, host_resource.host_resource(), info); | |
605 } | |
606 | |
607 void PPB_Flash_Proxy::OnHostMsgGetSetting(PP_Instance instance, | 373 void PPB_Flash_Proxy::OnHostMsgGetSetting(PP_Instance instance, |
608 PP_FlashSetting setting, | 374 PP_FlashSetting setting, |
609 SerializedVarReturnValue id) { | 375 SerializedVarReturnValue id) { |
610 EnterInstanceNoLock enter(instance); | 376 EnterInstanceNoLock enter(instance); |
611 if (enter.succeeded()) { | 377 if (enter.succeeded()) { |
612 id.Return(dispatcher(), | 378 id.Return(dispatcher(), |
613 enter.functions()->GetFlashAPI()->GetSetting( | 379 enter.functions()->GetFlashAPI()->GetSetting( |
614 instance, setting)); | 380 instance, setting)); |
615 } else { | 381 } else { |
616 id.Return(dispatcher(), PP_MakeUndefined()); | 382 id.Return(dispatcher(), PP_MakeUndefined()); |
617 } | 383 } |
618 } | 384 } |
619 | 385 |
620 void PPB_Flash_Proxy::OnHostMsgInvokePrinting(PP_Instance instance) { | 386 void PPB_Flash_Proxy::OnHostMsgInvokePrinting(PP_Instance instance) { |
621 // This function is actually implemented in the PPB_Flash_Print interface. | 387 // This function is actually implemented in the PPB_Flash_Print interface. |
622 // It's rarely used enough that we just request this interface when needed. | 388 // It's rarely used enough that we just request this interface when needed. |
623 const PPB_Flash_Print_1_0* print_interface = | 389 const PPB_Flash_Print_1_0* print_interface = |
624 static_cast<const PPB_Flash_Print_1_0*>( | 390 static_cast<const PPB_Flash_Print_1_0*>( |
625 dispatcher()->local_get_interface()(PPB_FLASH_PRINT_INTERFACE_1_0)); | 391 dispatcher()->local_get_interface()(PPB_FLASH_PRINT_INTERFACE_1_0)); |
626 if (print_interface) | 392 if (print_interface) |
627 print_interface->InvokePrinting(instance); | 393 print_interface->InvokePrinting(instance); |
628 } | 394 } |
629 | 395 |
630 } // namespace proxy | 396 } // namespace proxy |
631 } // namespace ppapi | 397 } // namespace ppapi |
OLD | NEW |