Replace NPObject usage in ppapi with gin
[chromium-blink-merge.git] / content / renderer / pepper / plugin_object.cc
blob7260b01bb0bf75d6ef81f9e24f76026a05d7de2e
1 // Copyright (c) 2011 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.
5 #include "content/renderer/pepper/plugin_object.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h"
13 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
14 #include "content/renderer/pepper/pepper_try_catch.h"
15 #include "content/renderer/pepper/plugin_module.h"
16 #include "content/renderer/pepper/v8_var_converter.h"
17 #include "gin/arguments.h"
18 #include "gin/converter.h"
19 #include "gin/function_template.h"
20 #include "gin/handle.h"
21 #include "gin/interceptor.h"
22 #include "gin/object_template_builder.h"
23 #include "gin/public/gin_embedders.h"
24 #include "ppapi/c/dev/ppb_var_deprecated.h"
25 #include "ppapi/c/dev/ppp_class_deprecated.h"
26 #include "ppapi/c/pp_resource.h"
27 #include "ppapi/c/pp_var.h"
28 #include "ppapi/shared_impl/ppapi_globals.h"
29 #include "ppapi/shared_impl/resource_tracker.h"
30 #include "ppapi/shared_impl/var.h"
31 #include "ppapi/shared_impl/var_tracker.h"
33 using ppapi::PpapiGlobals;
34 using ppapi::ScopedPPVar;
35 using ppapi::ScopedPPVarArray;
36 using ppapi::StringVar;
37 using ppapi::Var;
39 namespace content {
41 namespace {
43 const char kInvalidValueException[] = "Error: Invalid value";
45 } // namespace
47 // PluginObject ----------------------------------------------------------------
49 PluginObject::~PluginObject() {
50 if (instance_) {
51 ppp_class_->Deallocate(ppp_class_data_);
52 instance_->RemovePluginObject(this);
56 // static
57 gin::WrapperInfo PluginObject::kWrapperInfo = {gin::kEmbedderNativeGin};
59 // static
60 PluginObject* PluginObject::FromV8Object(v8::Isolate* isolate,
61 v8::Handle<v8::Object> v8_object) {
62 PluginObject* plugin_object;
63 if (!v8_object.IsEmpty() &&
64 gin::ConvertFromV8(isolate, v8_object, &plugin_object)) {
65 return plugin_object;
67 return NULL;
70 // static
71 PP_Var PluginObject::Create(PepperPluginInstanceImpl* instance,
72 const PPP_Class_Deprecated* ppp_class,
73 void* ppp_class_data) {
74 PepperTryCatchVar try_catch(instance, NULL);
75 gin::Handle<PluginObject> object =
76 gin::CreateHandle(instance->GetIsolate(),
77 new PluginObject(instance, ppp_class, ppp_class_data));
78 ScopedPPVar result = try_catch.FromV8(object.ToV8());
79 DCHECK(!try_catch.HasException());
80 return result.Release();
83 v8::Local<v8::Value> PluginObject::GetNamedProperty(
84 v8::Isolate* isolate,
85 const std::string& identifier) {
86 ScopedPPVar identifier_var(ScopedPPVar::PassRef(),
87 StringVar::StringToPPVar(identifier));
88 return GetPropertyOrMethod(instance_->GetIsolate(), identifier_var.get());
91 std::vector<std::string> PluginObject::EnumerateNamedProperties(
92 v8::Isolate* isolate) {
93 std::vector<std::string> result;
94 if (!instance_)
95 return result;
97 PepperTryCatchV8 try_catch(instance_, V8VarConverter::kAllowObjectVars,
98 isolate);
100 PP_Var* name_vars;
101 uint32_t count = 0;
102 ppp_class_->GetAllPropertyNames(ppp_class_data_, &count, &name_vars,
103 try_catch.exception());
104 ScopedPPVarArray scoped_name_vars(
105 ScopedPPVarArray::PassPPBMemoryAllocatedArray(), name_vars, count);
107 if (try_catch.ThrowException())
108 return result;
110 for (uint32_t i = 0; i < count; ++i) {
111 StringVar* string_var = StringVar::FromPPVar(name_vars[i]);
112 if (string_var) {
113 result.push_back(string_var->value());
114 } else {
115 try_catch.ThrowException(kInvalidValueException);
116 result.clear();
117 return result;
121 return result;
124 void PluginObject::InstanceDeleted() {
125 instance_ = NULL;
128 PluginObject::PluginObject(PepperPluginInstanceImpl* instance,
129 const PPP_Class_Deprecated* ppp_class,
130 void* ppp_class_data)
131 : gin::NamedPropertyInterceptor(instance->GetIsolate(), this),
132 instance_(instance),
133 ppp_class_(ppp_class),
134 ppp_class_data_(ppp_class_data),
135 weak_factory_(this) {
136 instance_->AddPluginObject(this);
139 gin::ObjectTemplateBuilder PluginObject::GetObjectTemplateBuilder(
140 v8::Isolate* isolate) {
141 return Wrappable<PluginObject>::GetObjectTemplateBuilder(isolate)
142 .AddNamedPropertyInterceptor();
145 v8::Local<v8::Value> PluginObject::GetPropertyOrMethod(v8::Isolate* isolate,
146 PP_Var identifier_var) {
147 if (!instance_)
148 return v8::Local<v8::Value>();
150 PepperTryCatchV8 try_catch(instance_, V8VarConverter::kAllowObjectVars,
151 isolate);
152 bool has_property =
153 ppp_class_->HasProperty(ppp_class_data_, identifier_var,
154 try_catch.exception());
155 if (try_catch.ThrowException())
156 return v8::Local<v8::Value>();
158 if (has_property) {
159 ScopedPPVar result_var(ScopedPPVar::PassRef(),
160 ppp_class_->GetProperty(ppp_class_data_, identifier_var,
161 try_catch.exception()));
162 if (try_catch.ThrowException())
163 return v8::Local<v8::Value>();
165 v8::Handle<v8::Value> result = try_catch.ToV8(result_var.get());
166 if (try_catch.ThrowException())
167 return v8::Local<v8::Value>();
169 return result;
172 bool has_method = identifier_var.type == PP_VARTYPE_STRING &&
173 ppp_class_->HasMethod(ppp_class_data_, identifier_var,
174 try_catch.exception());
175 if (try_catch.ThrowException())
176 return v8::Local<v8::Value>();
178 if (has_method) {
179 const std::string& identifier =
180 StringVar::FromPPVar(identifier_var)->value();
181 return gin::CreateFunctionTemplate(isolate,
182 base::Bind(&PluginObject::Call,
183 weak_factory_.GetWeakPtr(),
184 identifier))->GetFunction();
187 return v8::Local<v8::Value>();
190 void PluginObject::Call(const std::string& identifier,
191 gin::Arguments* args) {
192 if (!instance_)
193 return;
195 PepperTryCatchV8 try_catch(instance_, V8VarConverter::kAllowObjectVars,
196 args->isolate());
197 ScopedPPVar identifier_var(ScopedPPVar::PassRef(),
198 StringVar::StringToPPVar(identifier));
199 ScopedPPVarArray argument_vars(args->Length());
201 for (uint32_t i = 0; i < argument_vars.size(); ++i) {
202 v8::Handle<v8::Value> arg;
203 if (!args->GetNext(&arg)) {
204 NOTREACHED();
207 argument_vars.Set(i, try_catch.FromV8(arg));
208 if (try_catch.ThrowException())
209 return;
212 // For the OOP plugin case we need to grab a reference on the plugin module
213 // object to ensure that it is not destroyed courtesy an incoming
214 // ExecuteScript call which destroys the plugin module and in turn the
215 // dispatcher.
216 scoped_refptr<PluginModule> ref(instance_->module());
218 ScopedPPVar result_var(ScopedPPVar::PassRef(),
219 ppp_class_->Call(ppp_class_data_, identifier_var.get(),
220 argument_vars.size(), argument_vars.get(),
221 try_catch.exception()));
222 if (try_catch.ThrowException())
223 return;
225 v8::Handle<v8::Value> result = try_catch.ToV8(result_var.get());
226 if (try_catch.ThrowException())
227 return;
229 args->Return(result);
232 } // namespace content