Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1485)

Side by Side Diff: extensions/renderer/api_binding.cc

Issue 2469593002: [Extensions Bindings] Add Events support (Closed)
Patch Set: . Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 #include "extensions/renderer/api_binding.h" 5 #include "extensions/renderer/api_binding.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
11 #include "base/values.h" 11 #include "base/values.h"
12 #include "extensions/common/extension_api.h" 12 #include "extensions/common/extension_api.h"
13 #include "extensions/renderer/api_event_handler.h"
13 #include "extensions/renderer/v8_helpers.h" 14 #include "extensions/renderer/v8_helpers.h"
14 #include "gin/arguments.h" 15 #include "gin/arguments.h"
15 #include "gin/per_context_data.h" 16 #include "gin/per_context_data.h"
16 17
17 namespace extensions { 18 namespace extensions {
18 19
19 namespace { 20 namespace {
20 21
21 const char kExtensionAPIPerContextKey[] = "extension_api_binding"; 22 const char kExtensionAPIPerContextKey[] = "extension_api_binding";
22 23
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 } 157 }
157 158
158 } // namespace 159 } // namespace
159 160
160 APIBinding::APIPerContextData::APIPerContextData() {} 161 APIBinding::APIPerContextData::APIPerContextData() {}
161 APIBinding::APIPerContextData::~APIPerContextData() {} 162 APIBinding::APIPerContextData::~APIPerContextData() {}
162 163
163 APIBinding::APIBinding(const std::string& api_name, 164 APIBinding::APIBinding(const std::string& api_name,
164 const base::ListValue& function_definitions, 165 const base::ListValue& function_definitions,
165 const base::ListValue* type_definitions, 166 const base::ListValue* type_definitions,
167 const base::ListValue* event_definitions,
166 const APIMethodCallback& callback, 168 const APIMethodCallback& callback,
167 ArgumentSpec::RefMap* type_refs) 169 ArgumentSpec::RefMap* type_refs)
168 : api_name_(api_name), 170 : api_name_(api_name),
169 method_callback_(callback), 171 method_callback_(callback),
170 type_refs_(type_refs), 172 type_refs_(type_refs),
171 weak_factory_(this) { 173 weak_factory_(this) {
172 DCHECK(!method_callback_.is_null()); 174 DCHECK(!method_callback_.is_null());
173 for (const auto& func : function_definitions) { 175 for (const auto& func : function_definitions) {
174 const base::DictionaryValue* func_dict = nullptr; 176 const base::DictionaryValue* func_dict = nullptr;
175 CHECK(func->GetAsDictionary(&func_dict)); 177 CHECK(func->GetAsDictionary(&func_dict));
176 std::string name; 178 std::string name;
177 CHECK(func_dict->GetString("name", &name)); 179 CHECK(func_dict->GetString("name", &name));
178 std::unique_ptr<APISignature> spec = GetAPISignature(*func_dict); 180 std::unique_ptr<APISignature> spec = GetAPISignature(*func_dict);
179 signatures_[name] = std::move(spec); 181 signatures_[name] = std::move(spec);
180 } 182 }
181 if (type_definitions) { 183 if (type_definitions) {
182 for (const auto& type : *type_definitions) { 184 for (const auto& type : *type_definitions) {
183 const base::DictionaryValue* type_dict = nullptr; 185 const base::DictionaryValue* type_dict = nullptr;
184 CHECK(type->GetAsDictionary(&type_dict)); 186 CHECK(type->GetAsDictionary(&type_dict));
185 std::string id; 187 std::string id;
186 CHECK(type_dict->GetString("id", &id)); 188 CHECK(type_dict->GetString("id", &id));
187 DCHECK(type_refs->find(id) == type_refs->end()); 189 DCHECK(type_refs->find(id) == type_refs->end());
188 // TODO(devlin): refs are sometimes preceeded by the API namespace; we 190 // TODO(devlin): refs are sometimes preceeded by the API namespace; we
189 // might need to take that into account. 191 // might need to take that into account.
190 (*type_refs)[id] = base::MakeUnique<ArgumentSpec>(*type_dict); 192 (*type_refs)[id] = base::MakeUnique<ArgumentSpec>(*type_dict);
191 } 193 }
192 } 194 }
195 if (event_definitions) {
196 event_names_.reserve(event_definitions->GetSize());
197 for (const auto& event : *event_definitions) {
198 const base::DictionaryValue* event_dict = nullptr;
199 CHECK(event->GetAsDictionary(&event_dict));
200 std::string name;
201 CHECK(event_dict->GetString("name", &name));
202 event_names_.push_back(std::move(name));
203 }
204 }
193 } 205 }
194 206
195 APIBinding::~APIBinding() {} 207 APIBinding::~APIBinding() {}
196 208
197 v8::Local<v8::Object> APIBinding::CreateInstance(v8::Local<v8::Context> context, 209 v8::Local<v8::Object> APIBinding::CreateInstance(
198 v8::Isolate* isolate) { 210 v8::Local<v8::Context> context,
211 v8::Isolate* isolate,
212 APIEventHandler* event_handler) {
199 // TODO(devlin): APIs may change depending on which features are available, 213 // TODO(devlin): APIs may change depending on which features are available,
200 // but we should be able to cache the unconditional methods on an object 214 // but we should be able to cache the unconditional methods on an object
201 // template, create the object, and then add any conditional methods. 215 // template, create the object, and then add any conditional methods.
202 v8::Local<v8::Object> object = v8::Object::New(isolate); 216 v8::Local<v8::Object> object = v8::Object::New(isolate);
203 gin::PerContextData* per_context_data = gin::PerContextData::From(context); 217 gin::PerContextData* per_context_data = gin::PerContextData::From(context);
204 DCHECK(per_context_data); 218 DCHECK(per_context_data);
205 APIPerContextData* data = static_cast<APIPerContextData*>( 219 APIPerContextData* data = static_cast<APIPerContextData*>(
206 per_context_data->GetUserData(kExtensionAPIPerContextKey)); 220 per_context_data->GetUserData(kExtensionAPIPerContextKey));
207 if (!data) { 221 if (!data) {
208 auto api_data = base::MakeUnique<APIPerContextData>(); 222 auto api_data = base::MakeUnique<APIPerContextData>();
(...skipping 13 matching lines...) Expand all
222 v8::External::New(isolate, handler_callback.get()), 236 v8::External::New(isolate, handler_callback.get()),
223 0, v8::ConstructorBehavior::kThrow); 237 0, v8::ConstructorBehavior::kThrow);
224 data->context_callbacks.push_back(std::move(handler_callback)); 238 data->context_callbacks.push_back(std::move(handler_callback));
225 v8::Maybe<bool> success = object->CreateDataProperty( 239 v8::Maybe<bool> success = object->CreateDataProperty(
226 context, gin::StringToSymbol(isolate, sig.first), 240 context, gin::StringToSymbol(isolate, sig.first),
227 maybe_function.ToLocalChecked()); 241 maybe_function.ToLocalChecked());
228 DCHECK(success.IsJust()); 242 DCHECK(success.IsJust());
229 DCHECK(success.FromJust()); 243 DCHECK(success.FromJust());
230 } 244 }
231 245
246 for (const std::string& event_name : event_names_) {
247 std::string full_event_name =
248 base::StringPrintf("%s.%s", api_name_.c_str(), event_name.c_str());
249 v8::Local<v8::Object> event =
250 event_handler->CreateEventInstance(full_event_name, context);
251 DCHECK(!event.IsEmpty());
252 v8::Maybe<bool> success = object->CreateDataProperty(
253 context, gin::StringToSymbol(isolate, event_name), event);
254 DCHECK(success.IsJust());
255 DCHECK(success.FromJust());
256 }
257
232 return object; 258 return object;
233 } 259 }
234 260
235 void APIBinding::HandleCall(const std::string& name, 261 void APIBinding::HandleCall(const std::string& name,
236 const APISignature* signature, 262 const APISignature* signature,
237 gin::Arguments* arguments) { 263 gin::Arguments* arguments) {
238 std::string error; 264 std::string error;
239 v8::Isolate* isolate = arguments->isolate(); 265 v8::Isolate* isolate = arguments->isolate();
240 v8::HandleScope handle_scope(isolate); 266 v8::HandleScope handle_scope(isolate);
241 std::unique_ptr<base::ListValue> parsed_arguments; 267 std::unique_ptr<base::ListValue> parsed_arguments;
(...skipping 13 matching lines...) Expand all
255 return; 281 return;
256 } 282 }
257 283
258 // Since this is called synchronously from the JS entry point, 284 // Since this is called synchronously from the JS entry point,
259 // GetCurrentContext() should always be correct. 285 // GetCurrentContext() should always be correct.
260 method_callback_.Run(name, std::move(parsed_arguments), isolate, 286 method_callback_.Run(name, std::move(parsed_arguments), isolate,
261 isolate->GetCurrentContext(), callback); 287 isolate->GetCurrentContext(), callback);
262 } 288 }
263 289
264 } // namespace extensions 290 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698