| 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 "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 5 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/linked_ptr.h" | 10 #include "base/memory/linked_ptr.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 | 94 |
| 95 #if defined(OS_WIN) | 95 #if defined(OS_WIN) |
| 96 #include "base/metrics/histogram.h" | 96 #include "base/metrics/histogram.h" |
| 97 #include "skia/ext/platform_canvas.h" | 97 #include "skia/ext/platform_canvas.h" |
| 98 #include "ui/gfx/codec/jpeg_codec.h" | 98 #include "ui/gfx/codec/jpeg_codec.h" |
| 99 #include "ui/gfx/gdi_util.h" | 99 #include "ui/gfx/gdi_util.h" |
| 100 #endif | 100 #endif |
| 101 | 101 |
| 102 using base::StringPrintf; | 102 using base::StringPrintf; |
| 103 using ppapi::InputEventData; | 103 using ppapi::InputEventData; |
| 104 using ppapi::PpapiGlobals; |
| 104 using ppapi::PPB_InputEvent_Shared; | 105 using ppapi::PPB_InputEvent_Shared; |
| 105 using ppapi::PpapiGlobals; | |
| 106 using ppapi::PPB_View_Shared; | 106 using ppapi::PPB_View_Shared; |
| 107 using ppapi::PPP_Instance_Combined; |
| 107 using ppapi::ScopedPPResource; | 108 using ppapi::ScopedPPResource; |
| 108 using ppapi::StringVar; | 109 using ppapi::StringVar; |
| 109 using ppapi::thunk::EnterResourceNoLock; | 110 using ppapi::thunk::EnterResourceNoLock; |
| 110 using ppapi::thunk::PPB_Buffer_API; | 111 using ppapi::thunk::PPB_Buffer_API; |
| 111 using ppapi::thunk::PPB_Graphics2D_API; | 112 using ppapi::thunk::PPB_Graphics2D_API; |
| 112 using ppapi::thunk::PPB_Graphics3D_API; | 113 using ppapi::thunk::PPB_Graphics3D_API; |
| 113 using ppapi::thunk::PPB_ImageData_API; | 114 using ppapi::thunk::PPB_ImageData_API; |
| 114 using ppapi::Var; | 115 using ppapi::Var; |
| 115 using ppapi::ViewData; | 116 using ppapi::ViewData; |
| 116 using WebKit::WebBindings; | 117 using WebKit::WebBindings; |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 WebKit::WebSecurityOrigin* security_origin) { | 275 WebKit::WebSecurityOrigin* security_origin) { |
| 275 PluginInstance* instance = HostGlobals::Get()->GetInstance(instance_id); | 276 PluginInstance* instance = HostGlobals::Get()->GetInstance(instance_id); |
| 276 if (!instance) | 277 if (!instance) |
| 277 return false; | 278 return false; |
| 278 | 279 |
| 279 WebElement plugin_element = instance->container()->element(); | 280 WebElement plugin_element = instance->container()->element(); |
| 280 *security_origin = plugin_element.document().securityOrigin(); | 281 *security_origin = plugin_element.document().securityOrigin(); |
| 281 return true; | 282 return true; |
| 282 } | 283 } |
| 283 | 284 |
| 285 // Convert the given vector to an array of C-strings. The strings in the |
| 286 // returned vector are only guaranteed valid so long as the vector of strings |
| 287 // is not modified. |
| 288 scoped_array<const char*> StringVectorToArgArray( |
| 289 const std::vector<std::string>& vector) { |
| 290 scoped_array<const char*> array(new const char*[vector.size()]); |
| 291 for (size_t i = 0; i < vector.size(); ++i) |
| 292 array[i] = vector[i].c_str(); |
| 293 return array.Pass(); |
| 294 } |
| 295 |
| 284 } // namespace | 296 } // namespace |
| 285 | 297 |
| 286 // static | 298 // static |
| 287 PluginInstance* PluginInstance::Create1_0(PluginDelegate* delegate, | 299 PluginInstance* PluginInstance::Create(PluginDelegate* delegate, |
| 288 PluginModule* module, | 300 PluginModule* module) { |
| 289 const void* ppp_instance_if_1_0) { | 301 base::Callback<const void*(const char*)> get_plugin_interface_func = |
| 290 const PPP_Instance_1_0* instance = | 302 base::Bind(&PluginModule::GetPluginInterface, module); |
| 291 static_cast<const PPP_Instance_1_0*>(ppp_instance_if_1_0); | 303 PPP_Instance_Combined* ppp_instance_combined = |
| 292 return new PluginInstance( | 304 PPP_Instance_Combined::Create(get_plugin_interface_func); |
| 293 delegate, | 305 if (!ppp_instance_combined) |
| 294 module, | 306 return NULL; |
| 295 new ::ppapi::PPP_Instance_Combined(*instance)); | 307 return new PluginInstance(delegate, module, ppp_instance_combined); |
| 296 } | |
| 297 | |
| 298 // static | |
| 299 PluginInstance* PluginInstance::Create1_1(PluginDelegate* delegate, | |
| 300 PluginModule* module, | |
| 301 const void* ppp_instance_if_1_1) { | |
| 302 const PPP_Instance_1_1* instance = | |
| 303 static_cast<const PPP_Instance_1_1*>(ppp_instance_if_1_1); | |
| 304 return new PluginInstance( | |
| 305 delegate, | |
| 306 module, | |
| 307 new ::ppapi::PPP_Instance_Combined(*instance)); | |
| 308 } | 308 } |
| 309 | 309 |
| 310 PluginInstance::PluginInstance( | 310 PluginInstance::PluginInstance( |
| 311 PluginDelegate* delegate, | 311 PluginDelegate* delegate, |
| 312 PluginModule* module, | 312 PluginModule* module, |
| 313 ::ppapi::PPP_Instance_Combined* instance_interface) | 313 ::ppapi::PPP_Instance_Combined* instance_interface) |
| 314 : delegate_(delegate), | 314 : delegate_(delegate), |
| 315 module_(module), | 315 module_(module), |
| 316 instance_interface_(instance_interface), | 316 instance_interface_(instance_interface), |
| 317 pp_instance_(0), | 317 pp_instance_(0), |
| 318 container_(NULL), | 318 container_(NULL), |
| 319 full_frame_(false), | 319 full_frame_(false), |
| 320 sent_initial_did_change_view_(false), | 320 sent_initial_did_change_view_(false), |
| 321 suppress_did_change_view_(false), | 321 view_change_weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 322 has_webkit_focus_(false), | 322 has_webkit_focus_(false), |
| 323 has_content_area_focus_(false), | 323 has_content_area_focus_(false), |
| 324 find_identifier_(-1), | 324 find_identifier_(-1), |
| 325 resource_creation_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 325 resource_creation_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 326 plugin_find_interface_(NULL), | 326 plugin_find_interface_(NULL), |
| 327 plugin_input_event_interface_(NULL), |
| 327 plugin_messaging_interface_(NULL), | 328 plugin_messaging_interface_(NULL), |
| 328 plugin_mouse_lock_interface_(NULL), | 329 plugin_mouse_lock_interface_(NULL), |
| 329 plugin_input_event_interface_(NULL), | 330 plugin_pdf_interface_(NULL), |
| 330 plugin_private_interface_(NULL), | 331 plugin_private_interface_(NULL), |
| 331 plugin_pdf_interface_(NULL), | |
| 332 plugin_selection_interface_(NULL), | 332 plugin_selection_interface_(NULL), |
| 333 plugin_textinput_interface_(NULL), | 333 plugin_textinput_interface_(NULL), |
| 334 plugin_zoom_interface_(NULL), | 334 plugin_zoom_interface_(NULL), |
| 335 checked_for_plugin_input_event_interface_(false), | 335 checked_for_plugin_input_event_interface_(false), |
| 336 checked_for_plugin_messaging_interface_(false), | 336 checked_for_plugin_messaging_interface_(false), |
| 337 plugin_print_interface_(NULL), | 337 plugin_print_interface_(NULL), |
| 338 plugin_graphics_3d_interface_(NULL), | 338 plugin_graphics_3d_interface_(NULL), |
| 339 always_on_top_(false), | 339 always_on_top_(false), |
| 340 fullscreen_container_(NULL), | 340 fullscreen_container_(NULL), |
| 341 flash_fullscreen_(false), | 341 flash_fullscreen_(false), |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 | 490 |
| 491 bool PluginInstance::Initialize(WebPluginContainer* container, | 491 bool PluginInstance::Initialize(WebPluginContainer* container, |
| 492 const std::vector<std::string>& arg_names, | 492 const std::vector<std::string>& arg_names, |
| 493 const std::vector<std::string>& arg_values, | 493 const std::vector<std::string>& arg_values, |
| 494 const GURL& plugin_url, | 494 const GURL& plugin_url, |
| 495 bool full_frame) { | 495 bool full_frame) { |
| 496 container_ = container; | 496 container_ = container; |
| 497 plugin_url_ = plugin_url; | 497 plugin_url_ = plugin_url; |
| 498 full_frame_ = full_frame; | 498 full_frame_ = full_frame; |
| 499 | 499 |
| 500 size_t argc = 0; | 500 argn_ = arg_names; |
| 501 scoped_array<const char*> argn(new const char*[arg_names.size()]); | 501 argv_ = arg_values; |
| 502 scoped_array<const char*> argv(new const char*[arg_names.size()]); | 502 scoped_array<const char*> argn_array(StringVectorToArgArray(argn_)); |
| 503 for (size_t i = 0; i < arg_names.size(); ++i) { | 503 scoped_array<const char*> argv_array(StringVectorToArgArray(argv_)); |
| 504 argn[argc] = arg_names[i].c_str(); | |
| 505 argv[argc] = arg_values[i].c_str(); | |
| 506 argc++; | |
| 507 } | |
| 508 | |
| 509 return PP_ToBool(instance_interface_->DidCreate(pp_instance(), | 504 return PP_ToBool(instance_interface_->DidCreate(pp_instance(), |
| 510 argc, | 505 argn_.size(), |
| 511 argn.get(), | 506 argn_array.get(), |
| 512 argv.get())); | 507 argv_array.get())); |
| 513 } | 508 } |
| 514 | 509 |
| 515 bool PluginInstance::HandleDocumentLoad(PPB_URLLoader_Impl* loader) { | 510 bool PluginInstance::HandleDocumentLoad(PPB_URLLoader_Impl* loader) { |
| 511 if (!document_loader_) |
| 512 document_loader_ = loader; |
| 513 DCHECK(loader == document_loader_.get()); |
| 514 |
| 516 return PP_ToBool(instance_interface_->HandleDocumentLoad( | 515 return PP_ToBool(instance_interface_->HandleDocumentLoad( |
| 517 pp_instance(), loader->pp_resource())); | 516 pp_instance(), loader->pp_resource())); |
| 518 } | 517 } |
| 519 | 518 |
| 520 bool PluginInstance::SendCompositionEventToPlugin(PP_InputEvent_Type type, | 519 bool PluginInstance::SendCompositionEventToPlugin(PP_InputEvent_Type type, |
| 521 const string16& text) { | 520 const string16& text) { |
| 522 std::vector<WebKit::WebCompositionUnderline> empty; | 521 std::vector<WebKit::WebCompositionUnderline> empty; |
| 523 return SendCompositionEventWithUnderlineInformationToPlugin( | 522 return SendCompositionEventWithUnderlineInformationToPlugin( |
| 524 type, text, empty, static_cast<int>(text.size()), | 523 type, text, empty, static_cast<int>(text.size()), |
| 525 static_cast<int>(text.size())); | 524 static_cast<int>(text.size())); |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1049 | 1048 |
| 1050 return !!plugin_zoom_interface_; | 1049 return !!plugin_zoom_interface_; |
| 1051 } | 1050 } |
| 1052 | 1051 |
| 1053 bool PluginInstance::PluginHasFocus() const { | 1052 bool PluginInstance::PluginHasFocus() const { |
| 1054 return has_webkit_focus_ && has_content_area_focus_; | 1053 return has_webkit_focus_ && has_content_area_focus_; |
| 1055 } | 1054 } |
| 1056 | 1055 |
| 1057 void PluginInstance::ScheduleAsyncDidChangeView( | 1056 void PluginInstance::ScheduleAsyncDidChangeView( |
| 1058 const ::ppapi::ViewData& previous_view) { | 1057 const ::ppapi::ViewData& previous_view) { |
| 1059 if (suppress_did_change_view_) | 1058 if (view_change_weak_ptr_factory_.HasWeakPtrs()) |
| 1060 return; // Already scheduled. | 1059 return; // Already scheduled. |
| 1061 suppress_did_change_view_ = true; | |
| 1062 MessageLoop::current()->PostTask( | 1060 MessageLoop::current()->PostTask( |
| 1063 FROM_HERE, base::Bind(&PluginInstance::SendAsyncDidChangeView, | 1061 FROM_HERE, base::Bind(&PluginInstance::SendAsyncDidChangeView, |
| 1064 this, previous_view)); | 1062 view_change_weak_ptr_factory_.GetWeakPtr(), |
| 1063 previous_view)); |
| 1065 } | 1064 } |
| 1066 | 1065 |
| 1067 void PluginInstance::SendAsyncDidChangeView(const ViewData& previous_view) { | 1066 void PluginInstance::SendAsyncDidChangeView(const ViewData& previous_view) { |
| 1068 DCHECK(suppress_did_change_view_); | 1067 // The bound callback that owns the weak pointer is still valid until after |
| 1069 suppress_did_change_view_ = false; | 1068 // this function returns. SendDidChangeView checks HasWeakPtrs, so we need to |
| 1069 // invalidate them here. |
| 1070 // NOTE: If we ever want to have more than one pending callback, it should |
| 1071 // use a different factory, or we should have a different strategy here. |
| 1072 view_change_weak_ptr_factory_.InvalidateWeakPtrs(); |
| 1070 SendDidChangeView(previous_view); | 1073 SendDidChangeView(previous_view); |
| 1071 } | 1074 } |
| 1072 | 1075 |
| 1073 void PluginInstance::SendDidChangeView(const ViewData& previous_view) { | 1076 void PluginInstance::SendDidChangeView(const ViewData& previous_view) { |
| 1074 // Don't send DidChangeView to crashed plugins. | 1077 // Don't send DidChangeView to crashed plugins. |
| 1075 if (module()->is_crashed()) | 1078 if (module()->is_crashed()) |
| 1076 return; | 1079 return; |
| 1077 | 1080 |
| 1078 if (suppress_did_change_view_ || | 1081 if (view_change_weak_ptr_factory_.HasWeakPtrs() || |
| 1079 (sent_initial_did_change_view_ && previous_view.Equals(view_data_))) | 1082 (sent_initial_did_change_view_ && previous_view.Equals(view_data_))) |
| 1080 return; // Nothing to update. | 1083 return; // Nothing to update. |
| 1081 | 1084 |
| 1082 const PP_Size& size = view_data_.rect.size; | 1085 const PP_Size& size = view_data_.rect.size; |
| 1083 // Avoid sending a notification with a huge rectangle. | 1086 // Avoid sending a notification with a huge rectangle. |
| 1084 if (size.width < 0 || size.width > kMaxPluginSideLength || | 1087 if (size.width < 0 || size.width > kMaxPluginSideLength || |
| 1085 size.height < 0 || size.height > kMaxPluginSideLength || | 1088 size.height < 0 || size.height > kMaxPluginSideLength || |
| 1086 // We know this won't overflow due to above checks. | 1089 // We know this won't overflow due to above checks. |
| 1087 static_cast<uint32>(size.width) * static_cast<uint32>(size.height) > | 1090 static_cast<uint32>(size.width) * static_cast<uint32>(size.height) > |
| 1088 kMaxPluginSize) { | 1091 kMaxPluginSize) { |
| (...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2082 components); | 2085 components); |
| 2083 } | 2086 } |
| 2084 | 2087 |
| 2085 PP_Var PluginInstance::GetPluginInstanceURL( | 2088 PP_Var PluginInstance::GetPluginInstanceURL( |
| 2086 PP_Instance instance, | 2089 PP_Instance instance, |
| 2087 PP_URLComponents_Dev* components) { | 2090 PP_URLComponents_Dev* components) { |
| 2088 return ::ppapi::PPB_URLUtil_Shared::GenerateURLReturn(plugin_url_, | 2091 return ::ppapi::PPB_URLUtil_Shared::GenerateURLReturn(plugin_url_, |
| 2089 components); | 2092 components); |
| 2090 } | 2093 } |
| 2091 | 2094 |
| 2095 bool PluginInstance::ResetAsProxied() { |
| 2096 base::Callback<const void*(const char*)> get_plugin_interface_func = |
| 2097 base::Bind(&PluginModule::GetPluginInterface, module_.get()); |
| 2098 PPP_Instance_Combined* ppp_instance_combined = |
| 2099 PPP_Instance_Combined::Create(get_plugin_interface_func); |
| 2100 if (!ppp_instance_combined) { |
| 2101 // The proxy must support at least one usable PPP_Instance interface. |
| 2102 NOTREACHED(); |
| 2103 return false; |
| 2104 } |
| 2105 instance_interface_.reset(ppp_instance_combined); |
| 2106 // Clear all PPP interfaces we may have cached. |
| 2107 plugin_find_interface_ = NULL; |
| 2108 plugin_input_event_interface_ = NULL; |
| 2109 plugin_messaging_interface_ = NULL; |
| 2110 plugin_mouse_lock_interface_ = NULL; |
| 2111 plugin_pdf_interface_ = NULL; |
| 2112 plugin_private_interface_ = NULL; |
| 2113 plugin_selection_interface_ = NULL; |
| 2114 plugin_textinput_interface_ = NULL; |
| 2115 plugin_zoom_interface_ = NULL; |
| 2116 |
| 2117 // Re-send the DidCreate event via the proxy. |
| 2118 scoped_array<const char*> argn_array(StringVectorToArgArray(argn_)); |
| 2119 scoped_array<const char*> argv_array(StringVectorToArgArray(argv_)); |
| 2120 if (!instance_interface_->DidCreate(pp_instance(), argn_.size(), |
| 2121 argn_array.get(), argv_array.get())) |
| 2122 return false; |
| 2123 |
| 2124 // Use a ViewData that looks like the initial DidChangeView event for the |
| 2125 // "previous" view. |
| 2126 ::ppapi::ViewData empty_view; |
| 2127 empty_view.is_page_visible = delegate_->IsPageVisible(); |
| 2128 // Clear sent_initial_did_change_view_ and cancel any pending DidChangeView |
| 2129 // event. This way, SendDidChangeView will send the "current" view |
| 2130 // immediately (before other events like HandleDocumentLoad). |
| 2131 sent_initial_did_change_view_ = false; |
| 2132 view_change_weak_ptr_factory_.InvalidateWeakPtrs(); |
| 2133 SendDidChangeView(empty_view); |
| 2134 |
| 2135 // If we received HandleDocumentLoad, re-send it now via the proxy. |
| 2136 if (document_loader_) |
| 2137 HandleDocumentLoad(document_loader_.get()); |
| 2138 return true; |
| 2139 } |
| 2140 |
| 2092 void PluginInstance::DoSetCursor(WebCursorInfo* cursor) { | 2141 void PluginInstance::DoSetCursor(WebCursorInfo* cursor) { |
| 2093 cursor_.reset(cursor); | 2142 cursor_.reset(cursor); |
| 2094 if (fullscreen_container_) { | 2143 if (fullscreen_container_) { |
| 2095 fullscreen_container_->DidChangeCursor(*cursor); | 2144 fullscreen_container_->DidChangeCursor(*cursor); |
| 2096 } else { | 2145 } else { |
| 2097 delegate()->DidChangeCursor(this, *cursor); | 2146 delegate()->DidChangeCursor(this, *cursor); |
| 2098 } | 2147 } |
| 2099 } | 2148 } |
| 2100 | 2149 |
| 2101 bool PluginInstance::CanAccessMainFrame() const { | 2150 bool PluginInstance::CanAccessMainFrame() const { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2152 screen_size_for_fullscreen_ = gfx::Size(); | 2201 screen_size_for_fullscreen_ = gfx::Size(); |
| 2153 WebElement element = container_->element(); | 2202 WebElement element = container_->element(); |
| 2154 element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_); | 2203 element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_); |
| 2155 element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_); | 2204 element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_); |
| 2156 element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_); | 2205 element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_); |
| 2157 element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_); | 2206 element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_); |
| 2158 } | 2207 } |
| 2159 | 2208 |
| 2160 } // namespace ppapi | 2209 } // namespace ppapi |
| 2161 } // namespace webkit | 2210 } // namespace webkit |
| OLD | NEW |