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"
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
;
43 const char kInvalidValueException
[] = "Error: Invalid value";
47 // PluginObject ----------------------------------------------------------------
49 PluginObject::~PluginObject() {
51 ppp_class_
->Deallocate(ppp_class_data_
);
52 instance_
->RemovePluginObject(this);
57 gin::WrapperInfo
PluginObject::kWrapperInfo
= {gin::kEmbedderNativeGin
};
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
)) {
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(
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
;
97 PepperTryCatchV8
try_catch(instance_
, V8VarConverter::kAllowObjectVars
,
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())
110 for (uint32_t i
= 0; i
< count
; ++i
) {
111 StringVar
* string_var
= StringVar::FromPPVar(name_vars
[i
]);
113 result
.push_back(string_var
->value());
115 try_catch
.ThrowException(kInvalidValueException
);
124 void PluginObject::InstanceDeleted() {
128 PluginObject::PluginObject(PepperPluginInstanceImpl
* instance
,
129 const PPP_Class_Deprecated
* ppp_class
,
130 void* ppp_class_data
)
131 : gin::NamedPropertyInterceptor(instance
->GetIsolate(), this),
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
) {
148 return v8::Local
<v8::Value
>();
150 PepperTryCatchV8
try_catch(instance_
, V8VarConverter::kAllowObjectVars
,
153 ppp_class_
->HasProperty(ppp_class_data_
, identifier_var
,
154 try_catch
.exception());
155 if (try_catch
.ThrowException())
156 return v8::Local
<v8::Value
>();
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
>();
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
>();
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
) {
195 PepperTryCatchV8
try_catch(instance_
, V8VarConverter::kAllowObjectVars
,
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
)) {
207 argument_vars
.Set(i
, try_catch
.FromV8(arg
));
208 if (try_catch
.ThrowException())
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
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())
225 v8::Handle
<v8::Value
> result
= try_catch
.ToV8(result_var
.get());
226 if (try_catch
.ThrowException())
229 args
->Return(result
);
232 } // namespace content