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

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

Issue 2469593002: [Extensions Bindings] Add Events support (Closed)
Patch Set: asantest 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
« no previous file with comments | « extensions/renderer/api_binding.h ('k') | extensions/renderer/api_binding_types.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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( 209 v8::Local<v8::Object> APIBinding::CreateInstance(
198 v8::Local<v8::Context> context, 210 v8::Local<v8::Context> context,
199 v8::Isolate* isolate, 211 v8::Isolate* isolate,
212 APIEventHandler* event_handler,
200 const AvailabilityCallback& is_available) { 213 const AvailabilityCallback& is_available) {
201 // TODO(devlin): APIs may change depending on which features are available, 214 // TODO(devlin): APIs may change depending on which features are available,
202 // but we should be able to cache the unconditional methods on an object 215 // but we should be able to cache the unconditional methods on an object
203 // template, create the object, and then add any conditional methods. Ideally, 216 // template, create the object, and then add any conditional methods. Ideally,
204 // this information should be available on the generated API specification. 217 // this information should be available on the generated API specification.
205 v8::Local<v8::Object> object = v8::Object::New(isolate); 218 v8::Local<v8::Object> object = v8::Object::New(isolate);
206 gin::PerContextData* per_context_data = gin::PerContextData::From(context); 219 gin::PerContextData* per_context_data = gin::PerContextData::From(context);
207 DCHECK(per_context_data); 220 DCHECK(per_context_data);
208 APIPerContextData* data = static_cast<APIPerContextData*>( 221 APIPerContextData* data = static_cast<APIPerContextData*>(
209 per_context_data->GetUserData(kExtensionAPIPerContextKey)); 222 per_context_data->GetUserData(kExtensionAPIPerContextKey));
(...skipping 19 matching lines...) Expand all
229 v8::External::New(isolate, handler_callback.get()), 242 v8::External::New(isolate, handler_callback.get()),
230 0, v8::ConstructorBehavior::kThrow); 243 0, v8::ConstructorBehavior::kThrow);
231 data->context_callbacks.push_back(std::move(handler_callback)); 244 data->context_callbacks.push_back(std::move(handler_callback));
232 v8::Maybe<bool> success = object->CreateDataProperty( 245 v8::Maybe<bool> success = object->CreateDataProperty(
233 context, gin::StringToSymbol(isolate, sig.first), 246 context, gin::StringToSymbol(isolate, sig.first),
234 maybe_function.ToLocalChecked()); 247 maybe_function.ToLocalChecked());
235 DCHECK(success.IsJust()); 248 DCHECK(success.IsJust());
236 DCHECK(success.FromJust()); 249 DCHECK(success.FromJust());
237 } 250 }
238 251
252 for (const std::string& event_name : event_names_) {
253 std::string full_event_name =
254 base::StringPrintf("%s.%s", api_name_.c_str(), event_name.c_str());
255 v8::Local<v8::Object> event =
256 event_handler->CreateEventInstance(full_event_name, context);
257 DCHECK(!event.IsEmpty());
258 v8::Maybe<bool> success = object->CreateDataProperty(
259 context, gin::StringToSymbol(isolate, event_name), event);
260 DCHECK(success.IsJust());
261 DCHECK(success.FromJust());
262 }
263
239 return object; 264 return object;
240 } 265 }
241 266
242 void APIBinding::HandleCall(const std::string& name, 267 void APIBinding::HandleCall(const std::string& name,
243 const APISignature* signature, 268 const APISignature* signature,
244 gin::Arguments* arguments) { 269 gin::Arguments* arguments) {
245 std::string error; 270 std::string error;
246 v8::Isolate* isolate = arguments->isolate(); 271 v8::Isolate* isolate = arguments->isolate();
247 v8::HandleScope handle_scope(isolate); 272 v8::HandleScope handle_scope(isolate);
248 std::unique_ptr<base::ListValue> parsed_arguments; 273 std::unique_ptr<base::ListValue> parsed_arguments;
(...skipping 13 matching lines...) Expand all
262 return; 287 return;
263 } 288 }
264 289
265 // Since this is called synchronously from the JS entry point, 290 // Since this is called synchronously from the JS entry point,
266 // GetCurrentContext() should always be correct. 291 // GetCurrentContext() should always be correct.
267 method_callback_.Run(name, std::move(parsed_arguments), isolate, 292 method_callback_.Run(name, std::move(parsed_arguments), isolate,
268 isolate->GetCurrentContext(), callback); 293 isolate->GetCurrentContext(), callback);
269 } 294 }
270 295
271 } // namespace extensions 296 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/api_binding.h ('k') | extensions/renderer/api_binding_types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698