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)); |
| 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_.is_undefined()) |
| 117 test_object_ = pp::VarPrivate(instance_, new TestObjectSO(instance_)); |
| 118 *var = test_object_; |
| 119 } |
| 120 |
| 121 pp::VarPrivate test_object_; |
| 122 }; |
| 123 |
| 124 class InstanceSO : public ScriptableBase { |
| 125 public: |
| 126 explicit InstanceSO(pp::InstancePrivate* instance) |
| 127 : ScriptableBase(instance) { |
| 128 methods_.insert(std::make_pair( |
| 129 "testExecuteScript", |
| 130 base::Bind(&InstanceSO::TestExecuteScript, base::Unretained(this)))); |
| 131 methods_.insert(std::make_pair( |
| 132 "testGetProperty", |
| 133 base::Bind(&InstanceSO::TestGetProperty, base::Unretained(this)))); |
| 134 methods_.insert(std::make_pair( |
| 135 "testPassTestObject", |
| 136 base::Bind(&InstanceSO::TestPassTestObject, base::Unretained(this)))); |
| 137 properties_.insert(std::make_pair( |
| 138 "testObject", base::Bind(&InstanceSO::TestObjectAccessor, |
| 139 base::Unretained(this)))); |
| 140 } |
| 141 ~InstanceSO() override {} |
| 142 |
| 143 private: |
68 // Requires one argument. The argument is passed through as-is to | 144 // Requires one argument. The argument is passed through as-is to |
69 // pp::InstancePrivate::ExecuteScript(). | 145 // pp::InstancePrivate::ExecuteScript(). |
70 pp::Var TestExecuteScript(const std::vector<pp::Var>& args, | 146 pp::Var TestExecuteScript(const std::vector<pp::Var>& args, |
71 pp::Var* exception) { | 147 pp::Var* exception) { |
72 if (args.size() != 1) { | 148 if (args.size() != 1) { |
73 *exception = pp::Var("testExecuteScript requires one argument"); | 149 *exception = pp::Var("testExecuteScript requires one argument"); |
74 return pp::Var(); | 150 return pp::Var(); |
75 } | 151 } |
76 return instance_->ExecuteScript(args[0], exception); | 152 return instance_->ExecuteScript(args[0], exception); |
77 } | 153 } |
78 | 154 |
79 // Requires one or more arguments. Roughly analogous to NPN_GetProperty. | 155 // Requires one or more arguments. Roughly analogous to NPN_GetProperty. |
80 // The arguments are the chain of properties to traverse, starting with the | 156 // The arguments are the chain of properties to traverse, starting with the |
81 // global context. | 157 // global context. |
82 pp::Var TestGetProperty(const std::vector<pp::Var>& args, | 158 pp::Var TestGetProperty(const std::vector<pp::Var>& args, |
83 pp::Var* exception) { | 159 pp::Var* exception) { |
84 if (args.size() < 1) { | 160 if (args.size() < 1) { |
85 *exception = pp::Var("testGetProperty requires at least one argument"); | 161 *exception = pp::Var("testGetProperty requires at least one argument"); |
86 return pp::Var(); | 162 return pp::Var(); |
87 } | 163 } |
88 pp::VarPrivate object = instance_->GetWindowObject(); | 164 pp::VarPrivate object = instance_->GetWindowObject(); |
89 for (const auto& arg : args) { | 165 for (const auto& arg : args) { |
90 if (!object.HasProperty(arg, exception)) | 166 if (!object.HasProperty(arg, exception)) |
91 return pp::Var(); | 167 return pp::Var(); |
92 object = object.GetProperty(arg, exception); | 168 object = object.GetProperty(arg, exception); |
93 } | 169 } |
94 return object; | 170 return object; |
95 } | 171 } |
96 | 172 |
97 pp::InstancePrivate* const instance_; | 173 // Requires 2 or more arguments. The first argument is the name of a function |
98 MethodMap methods_; | 174 // to invoke, and the second argument is a value to pass to that function. |
| 175 pp::Var TestPassTestObject(const std::vector<pp::Var>& args, |
| 176 pp::Var* exception) { |
| 177 if (args.size() < 2) { |
| 178 *exception = pp::Var("testPassTestObject requires at least 2 arguments"); |
| 179 return pp::Var(); |
| 180 } |
| 181 pp::VarPrivate object = instance_->GetWindowObject(); |
| 182 return object.Call(args[0], args[1], exception); |
| 183 } |
| 184 |
| 185 void TestObjectAccessor(bool set, pp::Var* var) { |
| 186 if (set) |
| 187 return; |
| 188 if (test_object_.is_undefined()) |
| 189 test_object_ = pp::VarPrivate(instance_, new TestObjectSO(instance_)); |
| 190 *var = test_object_; |
| 191 } |
| 192 |
| 193 pp::VarPrivate test_object_; |
99 }; | 194 }; |
100 | 195 |
101 class BlinkDeprecatedTestInstance : public pp::InstancePrivate { | 196 class BlinkDeprecatedTestInstance : public pp::InstancePrivate { |
102 public: | 197 public: |
103 explicit BlinkDeprecatedTestInstance(PP_Instance instance) | 198 explicit BlinkDeprecatedTestInstance(PP_Instance instance) |
104 : pp::InstancePrivate(instance) {} | 199 : pp::InstancePrivate(instance) {} |
105 ~BlinkDeprecatedTestInstance() override {} | 200 ~BlinkDeprecatedTestInstance() override { |
| 201 LogMessage("%s", "Destroying"); |
| 202 } |
106 | 203 |
107 bool Init(uint32_t argc, const char* argn[], const char* argv[]) { | 204 bool Init(uint32_t argc, const char* argn[], const char* argv[]) { |
108 return true; | 205 return true; |
109 } | 206 } |
110 | 207 |
111 // pp::InstancePrivate overrides: | 208 // pp::InstancePrivate overrides: |
112 pp::Var GetInstanceObject() override { | 209 pp::Var GetInstanceObject() override { |
113 if (instance_var_.is_undefined()) { | 210 if (instance_var_.is_undefined()) { |
114 instance_so_ = new InstanceSO(this); | 211 instance_so_ = new InstanceSO(this); |
115 instance_var_ = pp::VarPrivate(this, instance_so_); | 212 instance_var_ = pp::VarPrivate(this, instance_so_); |
116 } | 213 } |
117 return instance_var_; | 214 return instance_var_; |
118 } | 215 } |
119 | 216 |
| 217 void LogMessage(const char* format...) { |
| 218 va_list args; |
| 219 va_start(args, format); |
| 220 LogToConsoleWithSource(PP_LOGLEVEL_LOG, |
| 221 pp::Var("Blink Deprecated Test Plugin"), |
| 222 pp::Var(base::StringPrintV(format, args))); |
| 223 va_end(args); |
| 224 } |
| 225 |
120 private: | 226 private: |
121 pp::VarPrivate instance_var_; | 227 pp::VarPrivate instance_var_; |
122 // Owned by |instance_var_|. | 228 // Owned by |instance_var_|. |
123 InstanceSO* instance_so_; | 229 InstanceSO* instance_so_; |
124 }; | 230 }; |
125 | 231 |
126 class BlinkDeprecatedTestModule : public pp::Module { | 232 class BlinkDeprecatedTestModule : public pp::Module { |
127 public: | 233 public: |
128 BlinkDeprecatedTestModule() {} | 234 BlinkDeprecatedTestModule() {} |
129 ~BlinkDeprecatedTestModule() override {} | 235 ~BlinkDeprecatedTestModule() override {} |
130 | 236 |
131 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 237 virtual pp::Instance* CreateInstance(PP_Instance instance) { |
132 return new BlinkDeprecatedTestInstance(instance); | 238 return new BlinkDeprecatedTestInstance(instance); |
133 } | 239 } |
134 }; | 240 }; |
135 | 241 |
136 } // namespace | 242 } // namespace |
137 | 243 |
138 namespace pp { | 244 namespace pp { |
139 | 245 |
140 Module* CreateModule() { | 246 Module* CreateModule() { |
141 return new BlinkDeprecatedTestModule(); | 247 return new BlinkDeprecatedTestModule(); |
142 } | 248 } |
143 | 249 |
144 } // namespace pp | 250 } // namespace pp |
OLD | NEW |