summaryrefslogtreecommitdiffstats
path: root/webkit/plugins
diff options
context:
space:
mode:
authordmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-19 19:03:39 +0000
committerdmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-19 19:03:39 +0000
commitba7cc8c1eea511ffccdb57c66336ad84916bcdc1 (patch)
tree1a1b846cfbb03678bd6be459e1fd62433c124ab7 /webkit/plugins
parent533b73784cd84662b87827dddc92aaf8fc6786d6 (diff)
downloadchromium_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.cc5
-rw-r--r--webkit/plugins/ppapi/plugin_module.cc28
-rw-r--r--webkit/plugins/ppapi/plugin_module.h6
-rw-r--r--webkit/plugins/ppapi/ppapi_plugin_instance.cc135
-rw-r--r--webkit/plugins/ppapi/ppapi_plugin_instance.h44
-rw-r--r--webkit/plugins/ppapi/ppapi_unittest.cc7
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());
}