OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 // A simple C++ Pepper plugin for exercising deprecated PPAPI interfaces in | 5 // A simple C++ Pepper plugin for exercising deprecated PPAPI interfaces in |
6 // Blink layout tests. | 6 // Blink layout tests. |
7 // | 7 // |
8 // Most layout tests should prefer to use the normal Blink test plugin, with the | 8 // Most layout tests should prefer to use the normal Blink test plugin, with the |
9 // MIME type application/x-blink-test-plugin. For layout tests that absolutely | 9 // MIME type application/x-blink-test-plugin. For layout tests that absolutely |
10 // need to test deprecated synchronous scripting interfaces, this plugin can be | 10 // need to test deprecated synchronous scripting interfaces, this plugin can be |
11 // instantiated using the application/x-blink-deprecated-test-plugin MIME type. | 11 // instantiated using the application/x-blink-deprecated-test-plugin MIME type. |
12 | 12 |
13 #include <stdint.h> | 13 #include <stdint.h> |
14 | 14 |
15 #include <map> | 15 #include <map> |
16 #include <sstream> | 16 #include <sstream> |
17 #include <utility> | 17 #include <utility> |
18 | 18 |
19 #include "base/bind.h" | 19 #include "base/bind.h" |
20 #include "base/bind_helpers.h" | 20 #include "base/bind_helpers.h" |
21 #include "base/callback.h" | 21 #include "base/callback.h" |
22 #include "base/strings/stringprintf.h" | |
22 #include "ppapi/cpp/dev/scriptable_object_deprecated.h" | 23 #include "ppapi/cpp/dev/scriptable_object_deprecated.h" |
23 #include "ppapi/cpp/module.h" | 24 #include "ppapi/cpp/module.h" |
24 #include "ppapi/cpp/private/instance_private.h" | 25 #include "ppapi/cpp/private/instance_private.h" |
25 #include "ppapi/cpp/private/var_private.h" | 26 #include "ppapi/cpp/private/var_private.h" |
26 #include "ppapi/cpp/var.h" | 27 #include "ppapi/cpp/var.h" |
27 | 28 |
28 namespace { | 29 namespace { |
29 | 30 |
30 class InstanceSO : public pp::deprecated::ScriptableObject { | 31 class ScriptableBase : public pp::deprecated::ScriptableObject { |
31 public: | 32 public: |
32 explicit InstanceSO(pp::InstancePrivate* instance) : instance_(instance) { | 33 explicit ScriptableBase(pp::InstancePrivate* instance) |
33 methods_.insert(std::make_pair( | 34 : instance_(instance) {} |
34 "testExecuteScript", | 35 ~ScriptableBase() override {} |
35 base::Bind(&InstanceSO::TestExecuteScript, base::Unretained(this)))); | 36 |
36 methods_.insert(std::make_pair( | 37 // pp::deprecated::ScriptableObject overrides: |
37 "testGetProperty", | 38 bool HasMethod(const pp::Var& name, pp::Var* exception) override { |
38 base::Bind(&InstanceSO::TestGetProperty, base::Unretained(this)))); | 39 return FindMethod(name) != methods_.end(); |
39 } | 40 } |
40 | 41 |
41 // pp::deprecated::ScriptableObject overrides: | 42 bool HasProperty(const pp::Var& name, pp::Var* exception) override { |
42 bool HasMethod(const pp::Var& name, pp::Var* exception) { | 43 return FindProperty(name) != properties_.end(); |
43 return FindMethod(name) != methods_.end(); | |
44 } | 44 } |
45 | 45 |
46 pp::Var Call(const pp::Var& method_name, | 46 pp::Var Call(const pp::Var& method_name, |
47 const std::vector<pp::Var>& args, | 47 const std::vector<pp::Var>& args, |
48 pp::Var* exception) override { | 48 pp::Var* exception) override { |
49 auto method = FindMethod(method_name); | 49 auto method = FindMethod(method_name); |
50 if (method != methods_.end()) { | 50 if (method != methods_.end()) { |
51 return method->second.Run(args, exception); | 51 return method->second.Run(args, exception); |
52 } | 52 } |
53 | 53 |
54 return ScriptableObject::Call(method_name, args, exception); | 54 return ScriptableObject::Call(method_name, args, exception); |
55 } | 55 } |
56 | 56 |
57 private: | 57 pp::Var GetProperty(const pp::Var& name, pp::Var* exception) override { |
58 auto accessor = FindProperty(name); | |
59 if (accessor != properties_.end()) { | |
60 pp::Var value; | |
61 accessor->second.Run(false, &value); | |
62 return value; | |
63 } | |
64 return ScriptableObject::GetProperty(name, exception); | |
65 } | |
66 | |
67 void SetProperty(const pp::Var& name, | |
68 const pp::Var& value, | |
69 pp::Var* exception) override { | |
70 auto accessor = FindProperty(name); | |
71 if (accessor != properties_.end()) | |
72 accessor->second.Run(true, const_cast<pp::Var*>(&value)); | |
dcheng
2016/03/18 07:08:09
Heh
| |
73 else | |
74 ScriptableObject::SetProperty(name, value, exception); | |
75 } | |
76 | |
77 protected: | |
58 using MethodMap = | 78 using MethodMap = |
59 std::map<std::string, | 79 std::map<std::string, |
60 base::Callback<pp::Var(const std::vector<pp::Var>&, pp::Var*)>>; | 80 base::Callback<pp::Var(const std::vector<pp::Var>&, pp::Var*)>>; |
81 using PropertyMap = | |
82 std::map<std::string, base::Callback<void(bool, pp::Var*)>>; | |
83 | |
61 | 84 |
62 MethodMap::iterator FindMethod(const pp::Var& name) { | 85 MethodMap::iterator FindMethod(const pp::Var& name) { |
63 if (!name.is_string()) | 86 if (!name.is_string()) |
64 return methods_.end(); | 87 return methods_.end(); |
65 return methods_.find(name.AsString()); | 88 return methods_.find(name.AsString()); |
66 } | 89 } |
67 | 90 |
91 PropertyMap::iterator FindProperty(const pp::Var& name) { | |
92 if (!name.is_string()) | |
93 return properties_.end(); | |
94 return properties_.find(name.AsString()); | |
95 } | |
96 | |
97 pp::InstancePrivate* const instance_; | |
98 MethodMap methods_; | |
99 PropertyMap properties_; | |
100 }; | |
101 | |
102 class TestObjectSO : public ScriptableBase { | |
103 public: | |
104 explicit TestObjectSO(pp::InstancePrivate* instance) | |
105 : ScriptableBase(instance) { | |
106 properties_.insert(std::make_pair( | |
107 "testObject", | |
108 base::Bind(&TestObjectSO::TestObjectAccessor, base::Unretained(this)))); | |
109 } | |
110 ~TestObjectSO() override {} | |
111 | |
112 private: | |
113 void TestObjectAccessor(bool set, pp::Var* var) { | |
114 if (set) | |
115 return; | |
116 if (!test_object_) { | |
117 test_object_.reset(new TestObjectSO(instance_)); | |
118 test_object_var_ = pp::VarPrivate(instance_, test_object_.get()); | |
119 } | |
120 *var = test_object_var_; | |
121 } | |
122 | |
123 scoped_ptr<TestObjectSO> test_object_; | |
124 pp::VarPrivate test_object_var_; | |
125 }; | |
126 | |
127 class InstanceSO : public ScriptableBase { | |
128 public: | |
129 explicit InstanceSO(pp::InstancePrivate* instance) | |
130 : ScriptableBase(instance), log_destroy_(false) { | |
131 methods_.insert(std::make_pair( | |
132 "testExecuteScript", | |
133 base::Bind(&InstanceSO::TestExecuteScript, base::Unretained(this)))); | |
134 methods_.insert(std::make_pair( | |
135 "testGetProperty", | |
136 base::Bind(&InstanceSO::TestGetProperty, base::Unretained(this)))); | |
137 methods_.insert(std::make_pair( | |
138 "testPassTestObject", | |
139 base::Bind(&InstanceSO::TestPassTestObject, base::Unretained(this)))); | |
140 properties_.insert(std::make_pair( | |
141 "logDestroy", base::Bind(&InstanceSO::LogDestroyAccessor, | |
142 base::Unretained(this)))); | |
143 properties_.insert(std::make_pair( | |
144 "testObject", base::Bind(&InstanceSO::TestObjectAccessor, | |
145 base::Unretained(this)))); | |
146 } | |
147 ~InstanceSO() override {} | |
148 | |
149 private: | |
68 // Requires one argument. The argument is passed through as-is to | 150 // Requires one argument. The argument is passed through as-is to |
69 // pp::InstancePrivate::ExecuteScript(). | 151 // pp::InstancePrivate::ExecuteScript(). |
70 pp::Var TestExecuteScript(const std::vector<pp::Var>& args, | 152 pp::Var TestExecuteScript(const std::vector<pp::Var>& args, |
71 pp::Var* exception) { | 153 pp::Var* exception) { |
72 if (args.size() != 1) { | 154 if (args.size() != 1) { |
73 *exception = pp::Var("testExecuteScript requires one argument"); | 155 *exception = pp::Var("testExecuteScript requires one argument"); |
74 return pp::Var(); | 156 return pp::Var(); |
75 } | 157 } |
76 return instance_->ExecuteScript(args[0], exception); | 158 return instance_->ExecuteScript(args[0], exception); |
77 } | 159 } |
78 | 160 |
79 // Requires one or more arguments. Roughly analogous to NPN_GetProperty. | 161 // Requires one or more arguments. Roughly analogous to NPN_GetProperty. |
80 // The arguments are the chain of properties to traverse, starting with the | 162 // The arguments are the chain of properties to traverse, starting with the |
81 // global context. | 163 // global context. |
82 pp::Var TestGetProperty(const std::vector<pp::Var>& args, | 164 pp::Var TestGetProperty(const std::vector<pp::Var>& args, |
83 pp::Var* exception) { | 165 pp::Var* exception) { |
84 if (args.size() < 1) { | 166 if (args.size() < 1) { |
85 *exception = pp::Var("testGetProperty requires at least one argument"); | 167 *exception = pp::Var("testGetProperty requires at least one argument"); |
86 return pp::Var(); | 168 return pp::Var(); |
87 } | 169 } |
88 pp::VarPrivate object = instance_->GetWindowObject(); | 170 pp::VarPrivate object = instance_->GetWindowObject(); |
89 for (const auto& arg : args) { | 171 for (const auto& arg : args) { |
90 if (!object.HasProperty(arg, exception)) | 172 if (!object.HasProperty(arg, exception)) |
91 return pp::Var(); | 173 return pp::Var(); |
92 object = object.GetProperty(arg, exception); | 174 object = object.GetProperty(arg, exception); |
93 } | 175 } |
94 return object; | 176 return object; |
95 } | 177 } |
96 | 178 |
97 pp::InstancePrivate* const instance_; | 179 // Requires 2 or more arguments. The first argument is the name of a function |
98 MethodMap methods_; | 180 // to invoke, and the second argument is a value to pass to that function. |
181 pp::Var TestPassTestObject(const std::vector<pp::Var>& args, | |
182 pp::Var* exception) { | |
183 if (args.size() < 2) { | |
184 *exception = pp::Var("testPassTestObject requires at least 2 arguments"); | |
185 return pp::Var(); | |
186 } | |
187 pp::VarPrivate object = instance_->GetWindowObject(); | |
188 return object.Call(args[0], args[1], exception); | |
189 } | |
190 | |
191 void LogDestroyAccessor(bool set, pp::Var* var) { | |
dcheng
2016/03/18 07:08:09
Maybe we don't need this? We're unconditionally lo
piman
2016/03/18 18:41:13
You're right... the NPAPI one did this conditional
| |
192 if (set) | |
193 log_destroy_ = var->AsBool(); | |
194 else | |
195 *var = pp::Var(log_destroy_); | |
196 } | |
197 | |
198 void TestObjectAccessor(bool set, pp::Var* var) { | |
199 if (set) | |
200 return; | |
201 if (!test_object_) { | |
202 test_object_.reset(new TestObjectSO(instance_)); | |
203 test_object_var_ = pp::VarPrivate(instance_, test_object_.get()); | |
dcheng
2016/03/18 07:08:09
Some comments seemed to imply that pp::VarPrivate
piman
2016/03/18 18:41:13
You're absolutely right. Fixed.
| |
204 } | |
205 *var = test_object_var_; | |
206 } | |
207 | |
208 scoped_ptr<TestObjectSO> test_object_; | |
209 pp::VarPrivate test_object_var_; | |
210 bool log_destroy_; | |
99 }; | 211 }; |
100 | 212 |
101 class BlinkDeprecatedTestInstance : public pp::InstancePrivate { | 213 class BlinkDeprecatedTestInstance : public pp::InstancePrivate { |
102 public: | 214 public: |
103 explicit BlinkDeprecatedTestInstance(PP_Instance instance) | 215 explicit BlinkDeprecatedTestInstance(PP_Instance instance) |
104 : pp::InstancePrivate(instance) {} | 216 : pp::InstancePrivate(instance) {} |
105 ~BlinkDeprecatedTestInstance() override {} | 217 ~BlinkDeprecatedTestInstance() override { |
218 LogMessage("%s", "Destroying"); | |
219 } | |
106 | 220 |
107 bool Init(uint32_t argc, const char* argn[], const char* argv[]) { | 221 bool Init(uint32_t argc, const char* argn[], const char* argv[]) { |
108 return true; | 222 return true; |
109 } | 223 } |
110 | 224 |
111 // pp::InstancePrivate overrides: | 225 // pp::InstancePrivate overrides: |
112 pp::Var GetInstanceObject() override { | 226 pp::Var GetInstanceObject() override { |
113 if (instance_var_.is_undefined()) { | 227 if (instance_var_.is_undefined()) { |
114 instance_so_ = new InstanceSO(this); | 228 instance_so_ = new InstanceSO(this); |
115 instance_var_ = pp::VarPrivate(this, instance_so_); | 229 instance_var_ = pp::VarPrivate(this, instance_so_); |
116 } | 230 } |
117 return instance_var_; | 231 return instance_var_; |
118 } | 232 } |
119 | 233 |
234 void LogMessage(const char* format...) { | |
235 va_list args; | |
236 va_start(args, format); | |
237 LogToConsoleWithSource(PP_LOGLEVEL_LOG, | |
238 pp::Var("Blink Deprecated Test Plugin"), | |
239 pp::Var(base::StringPrintV(format, args))); | |
240 va_end(args); | |
241 } | |
242 | |
120 private: | 243 private: |
121 pp::VarPrivate instance_var_; | 244 pp::VarPrivate instance_var_; |
122 // Owned by |instance_var_|. | 245 // Owned by |instance_var_|. |
123 InstanceSO* instance_so_; | 246 InstanceSO* instance_so_; |
124 }; | 247 }; |
125 | 248 |
126 class BlinkDeprecatedTestModule : public pp::Module { | 249 class BlinkDeprecatedTestModule : public pp::Module { |
127 public: | 250 public: |
128 BlinkDeprecatedTestModule() {} | 251 BlinkDeprecatedTestModule() {} |
129 ~BlinkDeprecatedTestModule() override {} | 252 ~BlinkDeprecatedTestModule() override {} |
130 | 253 |
131 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 254 virtual pp::Instance* CreateInstance(PP_Instance instance) { |
132 return new BlinkDeprecatedTestInstance(instance); | 255 return new BlinkDeprecatedTestInstance(instance); |
133 } | 256 } |
134 }; | 257 }; |
135 | 258 |
136 } // namespace | 259 } // namespace |
137 | 260 |
138 namespace pp { | 261 namespace pp { |
139 | 262 |
140 Module* CreateModule() { | 263 Module* CreateModule() { |
141 return new BlinkDeprecatedTestModule(); | 264 return new BlinkDeprecatedTestModule(); |
142 } | 265 } |
143 | 266 |
144 } // namespace pp | 267 } // namespace pp |
OLD | NEW |