// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/nacl/renderer/progress_event.h" #include "base/bind.h" #include "base/location.h" #include "base/logging.h" #include "components/nacl/renderer/ppb_nacl_private.h" #include "content/public/renderer/pepper_plugin_instance.h" #include "ppapi/shared_impl/ppapi_globals.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/web/WebDOMResourceProgressEvent.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebElement.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebPluginContainer.h" #include "v8/include/v8.h" namespace nacl { namespace { blink::WebString EventTypeToString(PP_NaClEventType event_type) { switch (event_type) { case PP_NACL_EVENT_LOADSTART: return blink::WebString::fromUTF8("loadstart"); case PP_NACL_EVENT_PROGRESS: return blink::WebString::fromUTF8("progress"); case PP_NACL_EVENT_ERROR: return blink::WebString::fromUTF8("error"); case PP_NACL_EVENT_ABORT: return blink::WebString::fromUTF8("abort"); case PP_NACL_EVENT_LOAD: return blink::WebString::fromUTF8("load"); case PP_NACL_EVENT_LOADEND: return blink::WebString::fromUTF8("loadend"); case PP_NACL_EVENT_CRASH: return blink::WebString::fromUTF8("crash"); } NOTIMPLEMENTED(); return blink::WebString(); } void DispatchProgressEventOnMainThread(PP_Instance instance, const ProgressEvent &event) { content::PepperPluginInstance* plugin_instance = content::PepperPluginInstance::Get(instance); if (!plugin_instance) return; blink::WebPluginContainer* container = plugin_instance->GetContainer(); // It's possible that container() is NULL if the plugin has been removed from // the DOM (but the PluginInstance is not destroyed yet). if (!container) return; blink::WebLocalFrame* frame = container->element().document().frame(); if (!frame) return; v8::HandleScope handle_scope(plugin_instance->GetIsolate()); v8::Local context( plugin_instance->GetIsolate()->GetCurrentContext()); if (context.IsEmpty()) { // If there's no JavaScript on the stack, we have to make a new Context. context = v8::Context::New(plugin_instance->GetIsolate()); } v8::Context::Scope context_scope(context); if (!event.resource_url.empty()) { blink::WebString url_string = blink::WebString::fromUTF8( event.resource_url.data(), event.resource_url.size()); blink::WebDOMResourceProgressEvent blink_event( EventTypeToString(event.event_type), event.length_is_computable, event.loaded_bytes, event.total_bytes, url_string); container->element().dispatchEvent(blink_event); } else { blink::WebDOMProgressEvent blink_event(EventTypeToString(event.event_type), event.length_is_computable, event.loaded_bytes, event.total_bytes); container->element().dispatchEvent(blink_event); } } } // namespace void DispatchProgressEvent(PP_Instance instance, const ProgressEvent &event) { ppapi::PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostTask( FROM_HERE, base::Bind(&DispatchProgressEventOnMainThread, instance, event)); } } // namespace nacl