diff options
author | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-19 19:03:39 +0000 |
---|---|---|
committer | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-19 19:03:39 +0000 |
commit | ba7cc8c1eea511ffccdb57c66336ad84916bcdc1 (patch) | |
tree | 1a1b846cfbb03678bd6be459e1fd62433c124ab7 /webkit/plugins | |
parent | 533b73784cd84662b87827dddc92aaf8fc6786d6 (diff) | |
download | chromium_src-ba7cc8c1eea511ffccdb57c66336ad84916bcdc1.zip chromium_src-ba7cc8c1eea511ffccdb57c66336ad84916bcdc1.tar.gz chromium_src-ba7cc8c1eea511ffccdb57c66336ad84916bcdc1.tar.bz2 |
PPAPI/NaCl: Reinitialize some stuff when the ipc proxy starts.
Also refactor the PPP_Instance version checking so I don't have to write the fall-back from 1.1 to 1.0 yet again.
BUG=116317
TEST=
Review URL: https://chromiumcodereview.appspot.com/10543029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@143006 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/plugins')
-rw-r--r-- | webkit/plugins/ppapi/host_var_tracker_unittest.cc | 5 | ||||
-rw-r--r-- | webkit/plugins/ppapi/plugin_module.cc | 28 | ||||
-rw-r--r-- | webkit/plugins/ppapi/plugin_module.h | 6 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppapi_plugin_instance.cc | 135 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppapi_plugin_instance.h | 44 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppapi_unittest.cc | 7 |
6 files changed, 150 insertions, 75 deletions
diff --git a/webkit/plugins/ppapi/host_var_tracker_unittest.cc b/webkit/plugins/ppapi/host_var_tracker_unittest.cc index bb6025e..92c4119 100644 --- a/webkit/plugins/ppapi/host_var_tracker_unittest.cc +++ b/webkit/plugins/ppapi/host_var_tracker_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -85,8 +85,7 @@ class HostVarTrackerTest : public PpapiUnittest { TEST_F(HostVarTrackerTest, DeleteObjectVarWithInstance) { // Make a second instance (the test harness already creates & manages one). scoped_refptr<PluginInstance> instance2( - PluginInstance::Create1_0(delegate(), module(), - GetMockInterface(PPP_INSTANCE_INTERFACE_1_0))); + PluginInstance::Create(delegate(), module())); PP_Instance pp_instance2 = instance2->pp_instance(); // Make an object var. diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc index 3d7f072..a16f79a 100644 --- a/webkit/plugins/ppapi/plugin_module.cc +++ b/webkit/plugins/ppapi/plugin_module.cc @@ -495,6 +495,25 @@ void PluginModule::InitAsProxied( out_of_process_proxy_.reset(out_of_process_proxy); } +void PluginModule::InitAsProxiedNaCl( + PluginDelegate::OutOfProcessProxy* out_of_process_proxy, + PP_Instance instance) { + InitAsProxied(out_of_process_proxy); + // InitAsProxied (for the trusted/out-of-process case) initializes only the + // module, and one or more instances are added later. In this case, the + // PluginInstance was already created as in-process, so we missed the proxy + // AddInstance step and must do it now. + out_of_process_proxy_->AddInstance(instance); + + // In NaCl, we need to tell the instance to reset itself as proxied. This will + // clear cached interface pointers and send DidCreate (etc) to the plugin + // side of the proxy. + PluginInstance* plugin_instance = host_globals->GetInstance(instance); + if (!plugin_instance) + return; + plugin_instance->ResetAsProxied(); +} + // static const PPB_Core* PluginModule::GetCore() { return &core_interface; @@ -506,14 +525,7 @@ PluginModule::GetInterfaceFunc PluginModule::GetLocalGetInterfaceFunc() { } PluginInstance* PluginModule::CreateInstance(PluginDelegate* delegate) { - PluginInstance* instance(NULL); - const void* ppp_instance = GetPluginInterface(PPP_INSTANCE_INTERFACE_1_1); - if (ppp_instance) { - instance = PluginInstance::Create1_1(delegate, this, ppp_instance); - } else if ((ppp_instance = GetPluginInterface(PPP_INSTANCE_INTERFACE_1_0))) { - instance = PluginInstance::Create1_0(delegate, this, ppp_instance); - } - + PluginInstance* instance = PluginInstance::Create(delegate, this); if (!instance) { LOG(WARNING) << "Plugin doesn't support instance interface, failing."; return NULL; diff --git a/webkit/plugins/ppapi/plugin_module.h b/webkit/plugins/ppapi/plugin_module.h index 814ae3a..d9b0162 100644 --- a/webkit/plugins/ppapi/plugin_module.h +++ b/webkit/plugins/ppapi/plugin_module.h @@ -87,6 +87,12 @@ class WEBKIT_PLUGINS_EXPORT PluginModule : // ownership of the given pointer, even in the failure case. void InitAsProxied(PluginDelegate::OutOfProcessProxy* out_of_process_proxy); + // Initializes this module for the given NaCl proxy. This takes + // ownership of the given pointer, even in the failure case. + void InitAsProxiedNaCl( + PluginDelegate::OutOfProcessProxy* out_of_process_proxy, + PP_Instance instance); + static const PPB_Core* GetCore(); // Returns a pointer to the local GetInterface function for retrieving diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.cc b/webkit/plugins/ppapi/ppapi_plugin_instance.cc index 5cb484f..3b6f263 100644 --- a/webkit/plugins/ppapi/ppapi_plugin_instance.cc +++ b/webkit/plugins/ppapi/ppapi_plugin_instance.cc @@ -101,9 +101,10 @@ using base::StringPrintf; using ppapi::InputEventData; -using ppapi::PPB_InputEvent_Shared; using ppapi::PpapiGlobals; +using ppapi::PPB_InputEvent_Shared; using ppapi::PPB_View_Shared; +using ppapi::PPP_Instance_Combined; using ppapi::ScopedPPResource; using ppapi::StringVar; using ppapi::thunk::EnterResourceNoLock; @@ -281,30 +282,29 @@ bool SecurityOriginForInstance(PP_Instance instance_id, return true; } -} // namespace - -// static -PluginInstance* PluginInstance::Create1_0(PluginDelegate* delegate, - PluginModule* module, - const void* ppp_instance_if_1_0) { - const PPP_Instance_1_0* instance = - static_cast<const PPP_Instance_1_0*>(ppp_instance_if_1_0); - return new PluginInstance( - delegate, - module, - new ::ppapi::PPP_Instance_Combined(*instance)); +// Convert the given vector to an array of C-strings. The strings in the +// returned vector are only guaranteed valid so long as the vector of strings +// is not modified. +scoped_array<const char*> StringVectorToArgArray( + const std::vector<std::string>& vector) { + scoped_array<const char*> array(new const char*[vector.size()]); + for (size_t i = 0; i < vector.size(); ++i) + array[i] = vector[i].c_str(); + return array.Pass(); } +} // namespace + // static -PluginInstance* PluginInstance::Create1_1(PluginDelegate* delegate, - PluginModule* module, - const void* ppp_instance_if_1_1) { - const PPP_Instance_1_1* instance = - static_cast<const PPP_Instance_1_1*>(ppp_instance_if_1_1); - return new PluginInstance( - delegate, - module, - new ::ppapi::PPP_Instance_Combined(*instance)); +PluginInstance* PluginInstance::Create(PluginDelegate* delegate, + PluginModule* module) { + base::Callback<const void*(const char*)> get_plugin_interface_func = + base::Bind(&PluginModule::GetPluginInterface, module); + PPP_Instance_Combined* ppp_instance_combined = + PPP_Instance_Combined::Create(get_plugin_interface_func); + if (!ppp_instance_combined) + return NULL; + return new PluginInstance(delegate, module, ppp_instance_combined); } PluginInstance::PluginInstance( @@ -318,17 +318,17 @@ PluginInstance::PluginInstance( container_(NULL), full_frame_(false), sent_initial_did_change_view_(false), - suppress_did_change_view_(false), + view_change_weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), has_webkit_focus_(false), has_content_area_focus_(false), find_identifier_(-1), resource_creation_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), plugin_find_interface_(NULL), + plugin_input_event_interface_(NULL), plugin_messaging_interface_(NULL), plugin_mouse_lock_interface_(NULL), - plugin_input_event_interface_(NULL), - plugin_private_interface_(NULL), plugin_pdf_interface_(NULL), + plugin_private_interface_(NULL), plugin_selection_interface_(NULL), plugin_textinput_interface_(NULL), plugin_zoom_interface_(NULL), @@ -497,22 +497,21 @@ bool PluginInstance::Initialize(WebPluginContainer* container, plugin_url_ = plugin_url; full_frame_ = full_frame; - size_t argc = 0; - scoped_array<const char*> argn(new const char*[arg_names.size()]); - scoped_array<const char*> argv(new const char*[arg_names.size()]); - for (size_t i = 0; i < arg_names.size(); ++i) { - argn[argc] = arg_names[i].c_str(); - argv[argc] = arg_values[i].c_str(); - argc++; - } - + argn_ = arg_names; + argv_ = arg_values; + scoped_array<const char*> argn_array(StringVectorToArgArray(argn_)); + scoped_array<const char*> argv_array(StringVectorToArgArray(argv_)); return PP_ToBool(instance_interface_->DidCreate(pp_instance(), - argc, - argn.get(), - argv.get())); + argn_.size(), + argn_array.get(), + argv_array.get())); } bool PluginInstance::HandleDocumentLoad(PPB_URLLoader_Impl* loader) { + if (!document_loader_) + document_loader_ = loader; + DCHECK(loader == document_loader_.get()); + return PP_ToBool(instance_interface_->HandleDocumentLoad( pp_instance(), loader->pp_resource())); } @@ -1056,17 +1055,21 @@ bool PluginInstance::PluginHasFocus() const { void PluginInstance::ScheduleAsyncDidChangeView( const ::ppapi::ViewData& previous_view) { - if (suppress_did_change_view_) + if (view_change_weak_ptr_factory_.HasWeakPtrs()) return; // Already scheduled. - suppress_did_change_view_ = true; MessageLoop::current()->PostTask( FROM_HERE, base::Bind(&PluginInstance::SendAsyncDidChangeView, - this, previous_view)); + view_change_weak_ptr_factory_.GetWeakPtr(), + previous_view)); } void PluginInstance::SendAsyncDidChangeView(const ViewData& previous_view) { - DCHECK(suppress_did_change_view_); - suppress_did_change_view_ = false; + // The bound callback that owns the weak pointer is still valid until after + // this function returns. SendDidChangeView checks HasWeakPtrs, so we need to + // invalidate them here. + // NOTE: If we ever want to have more than one pending callback, it should + // use a different factory, or we should have a different strategy here. + view_change_weak_ptr_factory_.InvalidateWeakPtrs(); SendDidChangeView(previous_view); } @@ -1075,7 +1078,7 @@ void PluginInstance::SendDidChangeView(const ViewData& previous_view) { if (module()->is_crashed()) return; - if (suppress_did_change_view_ || + if (view_change_weak_ptr_factory_.HasWeakPtrs() || (sent_initial_did_change_view_ && previous_view.Equals(view_data_))) return; // Nothing to update. @@ -2089,6 +2092,52 @@ PP_Var PluginInstance::GetPluginInstanceURL( components); } +bool PluginInstance::ResetAsProxied() { + base::Callback<const void*(const char*)> get_plugin_interface_func = + base::Bind(&PluginModule::GetPluginInterface, module_.get()); + PPP_Instance_Combined* ppp_instance_combined = + PPP_Instance_Combined::Create(get_plugin_interface_func); + if (!ppp_instance_combined) { + // The proxy must support at least one usable PPP_Instance interface. + NOTREACHED(); + return false; + } + instance_interface_.reset(ppp_instance_combined); + // Clear all PPP interfaces we may have cached. + plugin_find_interface_ = NULL; + plugin_input_event_interface_ = NULL; + plugin_messaging_interface_ = NULL; + plugin_mouse_lock_interface_ = NULL; + plugin_pdf_interface_ = NULL; + plugin_private_interface_ = NULL; + plugin_selection_interface_ = NULL; + plugin_textinput_interface_ = NULL; + plugin_zoom_interface_ = NULL; + + // Re-send the DidCreate event via the proxy. + scoped_array<const char*> argn_array(StringVectorToArgArray(argn_)); + scoped_array<const char*> argv_array(StringVectorToArgArray(argv_)); + if (!instance_interface_->DidCreate(pp_instance(), argn_.size(), + argn_array.get(), argv_array.get())) + return false; + + // Use a ViewData that looks like the initial DidChangeView event for the + // "previous" view. + ::ppapi::ViewData empty_view; + empty_view.is_page_visible = delegate_->IsPageVisible(); + // Clear sent_initial_did_change_view_ and cancel any pending DidChangeView + // event. This way, SendDidChangeView will send the "current" view + // immediately (before other events like HandleDocumentLoad). + sent_initial_did_change_view_ = false; + view_change_weak_ptr_factory_.InvalidateWeakPtrs(); + SendDidChangeView(empty_view); + + // If we received HandleDocumentLoad, re-send it now via the proxy. + if (document_loader_) + HandleDocumentLoad(document_loader_.get()); + return true; +} + void PluginInstance::DoSetCursor(WebCursorInfo* cursor) { cursor_.reset(cursor); if (fullscreen_container_) { diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.h b/webkit/plugins/ppapi/ppapi_plugin_instance.h index d1a9404e..7ae152a 100644 --- a/webkit/plugins/ppapi/ppapi_plugin_instance.h +++ b/webkit/plugins/ppapi/ppapi_plugin_instance.h @@ -96,15 +96,11 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance : public base::SupportsWeakPtr<PluginInstance>, public ::ppapi::PPB_Instance_Shared { public: - // Create and return a PluginInstance object which supports the - // given version. - static PluginInstance* Create1_0(PluginDelegate* delegate, - PluginModule* module, - const void* ppp_instance_if_1_0); - static PluginInstance* Create1_1(PluginDelegate* delegate, - PluginModule* module, - const void* ppp_instance_if_1_1); - + // Create and return a PluginInstance object which supports the most recent + // version of PPP_Instance possible by querying the given get_plugin_interface + // function. If the plugin does not support any valid PPP_Instance interface, + // returns NULL. + static PluginInstance* Create(PluginDelegate* delegate, PluginModule* module); // Delete should be called by the WebPlugin before this destructor. virtual ~PluginInstance(); @@ -405,6 +401,12 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance : PP_Instance instance, PP_URLComponents_Dev* components) OVERRIDE; + // Reset this instance as proxied. Resets cached interfaces to point to the + // proxy and re-sends DidCreate, DidChangeView, and HandleDocumentLoad (if + // necessary). + // This is for use with the NaCl proxy. + bool ResetAsProxied(); + private: // See the static Create functions above for creating PluginInstance objects. // This constructor is private so that we can hide the PPP_Instance_Combined @@ -513,11 +515,12 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance : // same as the default values. bool sent_initial_did_change_view_; - // Set to true when we've scheduled an asynchronous DidChangeView update for - // the purposes of consolidating updates. When this is set, code should - // update the view_data_ but not send updates. It will be cleared once the - // asynchronous update has been sent out. - bool suppress_did_change_view_; + // We use a weak ptr factory for scheduling DidChangeView events so that we + // can tell whether updates are pending and consolidate them. When there's + // already a weak ptr pending (HasWeakPtrs is true), code should update the + // view_data_ but not send updates. This also allows us to cancel scheduled + // view change events. + base::WeakPtrFactory<PluginInstance> view_change_weak_ptr_factory_; // The current device context for painting in 2D or 3D. scoped_refptr< ::ppapi::Resource> bound_graphics_; @@ -537,11 +540,11 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance : // The plugin-provided interfaces. const PPP_Find_Dev* plugin_find_interface_; + const PPP_InputEvent* plugin_input_event_interface_; const PPP_Messaging* plugin_messaging_interface_; const PPP_MouseLock* plugin_mouse_lock_interface_; - const PPP_InputEvent* plugin_input_event_interface_; - const PPP_Instance_Private* plugin_private_interface_; const PPP_Pdf* plugin_pdf_interface_; + const PPP_Instance_Private* plugin_private_interface_; const PPP_Selection_Dev* plugin_selection_interface_; const PPP_TextInput_Dev* plugin_textinput_interface_; const PPP_Zoom_Dev* plugin_zoom_interface_; @@ -652,6 +655,15 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance : // The Flash proxy is associated with the instance. PPB_Flash_Impl flash_impl_; + // We store the arguments so we can re-send them if we are reset to talk to + // NaCl via the IPC NaCl proxy. + std::vector<std::string> argn_; + std::vector<std::string> argv_; + + // This is NULL unless HandleDocumentLoad has called. In that case, we store + // the pointer so we can re-send it later if we are reset to talk to NaCl. + scoped_refptr<PPB_URLLoader_Impl> document_loader_; + DISALLOW_COPY_AND_ASSIGN(PluginInstance); }; diff --git a/webkit/plugins/ppapi/ppapi_unittest.cc b/webkit/plugins/ppapi/ppapi_unittest.cc index e245727..8b3fec50 100644 --- a/webkit/plugins/ppapi/ppapi_unittest.cc +++ b/webkit/plugins/ppapi/ppapi_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -82,10 +82,7 @@ void PpapiUnittest::SetUp() { ASSERT_TRUE(module_->InitAsInternalPlugin(entry_points)); // Initialize the mock instance. - instance_ = PluginInstance::Create1_0( - delegate_.get(), - module(), - GetMockInterface(PPP_INSTANCE_INTERFACE_1_0)); + instance_ = PluginInstance::Create(delegate_.get(), module()); } |