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. 4 5 #include "components/nacl/renderer/progress_event.h" 6 7 #include "base/bind.h" 8 #include "base/location.h" 9 #include "base/logging.h" 10 #include "base/message_loop/message_loop_proxy.h" 11 #include "content/public/renderer/pepper_plugin_instance.h" 12 #include "ppapi/c/private/ppb_nacl_private.h" 13 #include "ppapi/shared_impl/ppapi_globals.h" 14 #include "third_party/WebKit/public/platform/WebString.h" 15 #include "third_party/WebKit/public/web/WebDOMResourceProgressEvent.h" 16 #include "third_party/WebKit/public/web/WebDocument.h" 17 #include "third_party/WebKit/public/web/WebElement.h" 18 #include "third_party/WebKit/public/web/WebLocalFrame.h" 19 #include "third_party/WebKit/public/web/WebPluginContainer.h" 20 #include "v8/include/v8.h" 21 22 namespace nacl { 23 24 namespace { 25 blink::WebString EventTypeToString(PP_NaClEventType event_type) { 26 switch (event_type) { 27 case PP_NACL_EVENT_LOADSTART: 28 return blink::WebString::fromUTF8("loadstart"); 29 case PP_NACL_EVENT_PROGRESS: 30 return blink::WebString::fromUTF8("progress"); 31 case PP_NACL_EVENT_ERROR: 32 return blink::WebString::fromUTF8("error"); 33 case PP_NACL_EVENT_ABORT: 34 return blink::WebString::fromUTF8("abort"); 35 case PP_NACL_EVENT_LOAD: 36 return blink::WebString::fromUTF8("load"); 37 case PP_NACL_EVENT_LOADEND: 38 return blink::WebString::fromUTF8("loadend"); 39 case PP_NACL_EVENT_CRASH: 40 return blink::WebString::fromUTF8("crash"); 41 } 42 NOTIMPLEMENTED(); 43 return blink::WebString(); 44 } 45 46 void DispatchProgressEventOnMainThread(PP_Instance instance, 47 const ProgressEvent &event) { 48 content::PepperPluginInstance* plugin_instance = 49 content::PepperPluginInstance::Get(instance); 50 if (!plugin_instance) 51 return; 52 53 blink::WebPluginContainer* container = plugin_instance->GetContainer(); 54 // It's possible that container() is NULL if the plugin has been removed from 55 // the DOM (but the PluginInstance is not destroyed yet). 56 if (!container) 57 return; 58 blink::WebLocalFrame* frame = container->element().document().frame(); 59 if (!frame) 60 return; 61 v8::HandleScope handle_scope(plugin_instance->GetIsolate()); 62 v8::Local<v8::Context> context( 63 plugin_instance->GetIsolate()->GetCurrentContext()); 64 if (context.IsEmpty()) { 65 // If there's no JavaScript on the stack, we have to make a new Context. 66 context = v8::Context::New(plugin_instance->GetIsolate()); 67 } 68 v8::Context::Scope context_scope(context); 69 70 if (!event.resource_url.empty()) { 71 blink::WebString url_string = blink::WebString::fromUTF8( 72 event.resource_url.data(), event.resource_url.size()); 73 blink::WebDOMResourceProgressEvent blink_event( 74 EventTypeToString(event.event_type), 75 event.length_is_computable, 76 event.loaded_bytes, 77 event.total_bytes, 78 url_string); 79 container->element().dispatchEvent(blink_event); 80 } else { 81 blink::WebDOMProgressEvent blink_event(EventTypeToString(event.event_type), 82 event.length_is_computable, 83 event.loaded_bytes, 84 event.total_bytes); 85 container->element().dispatchEvent(blink_event); 86 } 87 } 88 89 } // namespace 90 91 void DispatchProgressEvent(PP_Instance instance, const ProgressEvent &event) { 92 ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( 93 FROM_HERE, 94 base::Bind(&DispatchProgressEventOnMainThread, instance, event)); 95 } 96 97 } // namespace nacl 98