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

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

Issue 2936673004: Revert of [Extensions Bindings] Avoid passing the event filter to JS (Closed)
Patch Set: Created 3 years, 6 months 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/event_bindings.h" 5 #include "extensions/renderer/event_bindings.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <map> 9 #include <map>
10 #include <memory> 10 #include <memory>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/lazy_instance.h" 14 #include "base/lazy_instance.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "components/crx_file/id_util.h" 16 #include "components/crx_file/id_util.h"
17 #include "content/public/child/v8_value_converter.h" 17 #include "content/public/child/v8_value_converter.h"
18 #include "content/public/renderer/render_frame.h" 18 #include "content/public/renderer/render_frame.h"
19 #include "content/public/renderer/render_thread.h" 19 #include "content/public/renderer/render_thread.h"
20 #include "content/public/renderer/render_view.h" 20 #include "content/public/renderer/render_view.h"
21 #include "extensions/common/constants.h" 21 #include "extensions/common/constants.h"
22 #include "extensions/common/event_filter.h" 22 #include "extensions/common/event_filter.h"
23 #include "extensions/common/extension.h" 23 #include "extensions/common/extension.h"
24 #include "extensions/common/extension_messages.h" 24 #include "extensions/common/extension_messages.h"
25 #include "extensions/common/extension_urls.h"
26 #include "extensions/common/value_counter.h" 25 #include "extensions/common/value_counter.h"
27 #include "extensions/renderer/extension_frame_helper.h" 26 #include "extensions/renderer/extension_frame_helper.h"
28 #include "extensions/renderer/script_context.h" 27 #include "extensions/renderer/script_context.h"
29 #include "extensions/renderer/service_worker_request_sender.h" 28 #include "extensions/renderer/service_worker_request_sender.h"
30 #include "extensions/renderer/worker_thread_dispatcher.h" 29 #include "extensions/renderer/worker_thread_dispatcher.h"
31 #include "gin/converter.h" 30 #include "gin/converter.h"
32 #include "url/gurl.h" 31 #include "url/gurl.h"
33 32
34 namespace extensions { 33 namespace extensions {
35 34
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 } 81 }
83 82
84 // Decrements the number of event-listeners for the given |event_name| and 83 // Decrements the number of event-listeners for the given |event_name| and
85 // ScriptContext. Returns the count after the increment. 84 // ScriptContext. Returns the count after the increment.
86 int DecrementEventListenerCount(ScriptContext* script_context, 85 int DecrementEventListenerCount(ScriptContext* script_context,
87 const std::string& event_name) { 86 const std::string& event_name) {
88 return --g_listener_counts 87 return --g_listener_counts
89 .Get()[GetKeyForScriptContext(script_context)][event_name]; 88 .Get()[GetKeyForScriptContext(script_context)][event_name];
90 } 89 }
91 90
91 EventFilteringInfo ParseFromObject(v8::Local<v8::Object> object,
92 v8::Isolate* isolate) {
93 EventFilteringInfo info;
94 v8::Local<v8::String> url(v8::String::NewFromUtf8(isolate, "url"));
95 if (object->Has(url)) {
96 v8::Local<v8::Value> url_value(object->Get(url));
97 info.SetURL(GURL(*v8::String::Utf8Value(url_value)));
98 }
99 v8::Local<v8::String> instance_id(
100 v8::String::NewFromUtf8(isolate, "instanceId"));
101 if (object->Has(instance_id)) {
102 v8::Local<v8::Value> instance_id_value(object->Get(instance_id));
103 info.SetInstanceID(instance_id_value->IntegerValue());
104 }
105 v8::Local<v8::String> service_type(
106 v8::String::NewFromUtf8(isolate, "serviceType"));
107 if (object->Has(service_type)) {
108 v8::Local<v8::Value> service_type_value(object->Get(service_type));
109 info.SetServiceType(*v8::String::Utf8Value(service_type_value));
110 }
111 v8::Local<v8::String> window_types(
112 v8::String::NewFromUtf8(isolate, "windowType"));
113 if (object->Has(window_types)) {
114 v8::Local<v8::Value> window_types_value(object->Get(window_types));
115 info.SetWindowType(*v8::String::Utf8Value(window_types_value));
116 }
117
118 v8::Local<v8::String> window_exposed(
119 v8::String::NewFromUtf8(isolate, "windowExposedByDefault"));
120 if (object->Has(window_exposed)) {
121 v8::Local<v8::Value> window_exposed_value(object->Get(window_exposed));
122 info.SetWindowExposedByDefault(
123 window_exposed_value.As<v8::Boolean>()->Value());
124 }
125
126 return info;
127 }
128
92 // Add a filter to |event_name| in |extension_id|, returning true if it 129 // Add a filter to |event_name| in |extension_id|, returning true if it
93 // was the first filter for that event in that extension. 130 // was the first filter for that event in that extension.
94 bool AddFilter(const std::string& event_name, 131 bool AddFilter(const std::string& event_name,
95 const std::string& extension_id, 132 const std::string& extension_id,
96 const base::DictionaryValue& filter) { 133 const base::DictionaryValue& filter) {
97 FilteredEventListenerKey key(extension_id, event_name); 134 FilteredEventListenerKey key(extension_id, event_name);
98 FilteredEventListenerCounts& all_counts = g_filtered_listener_counts.Get(); 135 FilteredEventListenerCounts& all_counts = g_filtered_listener_counts.Get();
99 FilteredEventListenerCounts::const_iterator counts = all_counts.find(key); 136 FilteredEventListenerCounts::const_iterator counts = all_counts.find(key);
100 if (counts == all_counts.end()) { 137 if (counts == all_counts.end()) {
101 counts = 138 counts =
(...skipping 17 matching lines...) Expand all
119 // |filter|. If there are more equivalent filters, or if there weren't any in 156 // |filter|. If there are more equivalent filters, or if there weren't any in
120 // the first place, it returns false. 157 // the first place, it returns false.
121 if (counts->second->Remove(*filter)) { 158 if (counts->second->Remove(*filter)) {
122 if (counts->second->is_empty()) 159 if (counts->second->is_empty())
123 all_counts.erase(counts); // Clean up if there are no more filters. 160 all_counts.erase(counts); // Clean up if there are no more filters.
124 return true; 161 return true;
125 } 162 }
126 return false; 163 return false;
127 } 164 }
128 165
129 // Returns a v8::Array containing the ids of the listeners that match the given
130 // |event_filter_dict| in the given |script_context|.
131 v8::Local<v8::Array> GetMatchingListeners(
132 ScriptContext* script_context,
133 const std::string& event_name,
134 const base::DictionaryValue& event_filter_dict) {
135 const EventFilter& event_filter = g_event_filter.Get();
136 EventFilteringInfo info(event_filter_dict);
137 v8::Isolate* isolate = script_context->isolate();
138 v8::Local<v8::Context> context = script_context->v8_context();
139
140 // Only match events routed to this context's RenderFrame or ones that don't
141 // have a routingId in their filter.
142 std::set<EventFilter::MatcherID> matched_event_filters =
143 event_filter.MatchEvent(event_name, info,
144 script_context->GetRenderFrame()->GetRoutingID());
145 v8::Local<v8::Array> array(
146 v8::Array::New(isolate, matched_event_filters.size()));
147 int i = 0;
148 for (EventFilter::MatcherID id : matched_event_filters) {
149 CHECK(array->CreateDataProperty(context, i++, v8::Integer::New(isolate, id))
150 .ToChecked());
151 }
152
153 return array;
154 }
155
156 } // namespace 166 } // namespace
157 167
158 EventBindings::EventBindings(ScriptContext* context) 168 EventBindings::EventBindings(ScriptContext* context)
159 : ObjectBackedNativeHandler(context) { 169 : ObjectBackedNativeHandler(context) {
160 RouteFunction("AttachEvent", base::Bind(&EventBindings::AttachEventHandler, 170 RouteFunction("AttachEvent", base::Bind(&EventBindings::AttachEventHandler,
161 base::Unretained(this))); 171 base::Unretained(this)));
162 RouteFunction("DetachEvent", base::Bind(&EventBindings::DetachEventHandler, 172 RouteFunction("DetachEvent", base::Bind(&EventBindings::DetachEventHandler,
163 base::Unretained(this))); 173 base::Unretained(this)));
164 RouteFunction( 174 RouteFunction(
165 "AttachFilteredEvent", 175 "AttachFilteredEvent",
166 base::Bind(&EventBindings::AttachFilteredEvent, base::Unretained(this))); 176 base::Bind(&EventBindings::AttachFilteredEvent, base::Unretained(this)));
167 RouteFunction("DetachFilteredEvent", 177 RouteFunction("DetachFilteredEvent",
168 base::Bind(&EventBindings::DetachFilteredEventHandler, 178 base::Bind(&EventBindings::DetachFilteredEventHandler,
169 base::Unretained(this))); 179 base::Unretained(this)));
180 RouteFunction("MatchAgainstEventFilter",
181 base::Bind(&EventBindings::MatchAgainstEventFilter,
182 base::Unretained(this)));
170 RouteFunction( 183 RouteFunction(
171 "AttachUnmanagedEvent", 184 "AttachUnmanagedEvent",
172 base::Bind(&EventBindings::AttachUnmanagedEvent, base::Unretained(this))); 185 base::Bind(&EventBindings::AttachUnmanagedEvent, base::Unretained(this)));
173 RouteFunction( 186 RouteFunction(
174 "DetachUnmanagedEvent", 187 "DetachUnmanagedEvent",
175 base::Bind(&EventBindings::DetachUnmanagedEvent, base::Unretained(this))); 188 base::Bind(&EventBindings::DetachUnmanagedEvent, base::Unretained(this)));
176 189
177 // It's safe to use base::Unretained here because |context| will always 190 // It's safe to use base::Unretained here because |context| will always
178 // outlive us. 191 // outlive us.
179 context->AddInvalidationObserver( 192 context->AddInvalidationObserver(
(...skipping 16 matching lines...) Expand all
196 if (managed_iter != managed_listeners.end()) { 209 if (managed_iter != managed_listeners.end()) {
197 auto event_iter = managed_iter->second.find(event_name); 210 auto event_iter = managed_iter->second.find(event_name);
198 if (event_iter != managed_iter->second.end() && event_iter->second > 0) { 211 if (event_iter != managed_iter->second.end() && event_iter->second > 0) {
199 return true; 212 return true;
200 } 213 }
201 } 214 }
202 215
203 return false; 216 return false;
204 } 217 }
205 218
206 // static
207 void EventBindings::DispatchEventInContext(
208 const std::string& event_name,
209 const base::ListValue* event_args,
210 const base::DictionaryValue* filtering_info,
211 ScriptContext* context) {
212 v8::HandleScope handle_scope(context->isolate());
213 v8::Context::Scope context_scope(context->v8_context());
214
215 v8::Local<v8::Array> listener_ids;
216 if (filtering_info && !filtering_info->empty())
217 listener_ids = GetMatchingListeners(context, event_name, *filtering_info);
218 else
219 listener_ids = v8::Array::New(context->isolate());
220
221 std::unique_ptr<content::V8ValueConverter> converter(
222 content::V8ValueConverter::create());
223 v8::Local<v8::Value> v8_args[] = {
224 gin::StringToSymbol(context->isolate(), event_name),
225 converter->ToV8Value(event_args, context->v8_context()), listener_ids,
226 };
227
228 context->module_system()->CallModuleMethodSafe(
229 kEventBindings, "dispatchEvent", arraysize(v8_args), v8_args);
230 }
231
232 void EventBindings::AttachEventHandler( 219 void EventBindings::AttachEventHandler(
233 const v8::FunctionCallbackInfo<v8::Value>& args) { 220 const v8::FunctionCallbackInfo<v8::Value>& args) {
234 CHECK_EQ(1, args.Length()); 221 CHECK_EQ(1, args.Length());
235 CHECK(args[0]->IsString()); 222 CHECK(args[0]->IsString());
236 AttachEvent(*v8::String::Utf8Value(args[0])); 223 AttachEvent(*v8::String::Utf8Value(args[0]));
237 } 224 }
238 225
239 void EventBindings::AttachEvent(const std::string& event_name) { 226 void EventBindings::AttachEvent(const std::string& event_name) {
240 if (!context()->HasAccessOrThrowError(event_name)) 227 if (!context()->HasAccessOrThrowError(event_name))
241 return; 228 return;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 if (is_lazy_context) { 288 if (is_lazy_context) {
302 sender->Send(new ExtensionHostMsg_RemoveLazyListener( 289 sender->Send(new ExtensionHostMsg_RemoveLazyListener(
303 extension_id, event_name, worker_thread_id)); 290 extension_id, event_name, worker_thread_id));
304 } 291 }
305 } 292 }
306 } 293 }
307 294
308 // MatcherID AttachFilteredEvent(string event_name, object filter) 295 // MatcherID AttachFilteredEvent(string event_name, object filter)
309 // event_name - Name of the event to attach. 296 // event_name - Name of the event to attach.
310 // filter - Which instances of the named event are we interested in. 297 // filter - Which instances of the named event are we interested in.
311 // returns the id assigned to the listener, which will be provided to calls to 298 // returns the id assigned to the listener, which will be returned from calls
312 // dispatchEvent(). 299 // to MatchAgainstEventFilter where this listener matches.
313 void EventBindings::AttachFilteredEvent( 300 void EventBindings::AttachFilteredEvent(
314 const v8::FunctionCallbackInfo<v8::Value>& args) { 301 const v8::FunctionCallbackInfo<v8::Value>& args) {
315 CHECK_EQ(2, args.Length()); 302 CHECK_EQ(2, args.Length());
316 CHECK(args[0]->IsString()); 303 CHECK(args[0]->IsString());
317 CHECK(args[1]->IsObject()); 304 CHECK(args[1]->IsObject());
318 305
319 std::string event_name = *v8::String::Utf8Value(args[0]); 306 std::string event_name = *v8::String::Utf8Value(args[0]);
320 if (!context()->HasAccessOrThrowError(event_name)) 307 if (!context()->HasAccessOrThrowError(event_name))
321 return; 308 return;
322 309
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 is_manual && ExtensionFrameHelper::IsContextForEventPage(context()); 363 is_manual && ExtensionFrameHelper::IsContextForEventPage(context());
377 content::RenderThread::Get()->Send( 364 content::RenderThread::Get()->Send(
378 new ExtensionHostMsg_RemoveFilteredListener( 365 new ExtensionHostMsg_RemoveFilteredListener(
379 extension_id, event_name, *event_matcher->value(), remove_lazy)); 366 extension_id, event_name, *event_matcher->value(), remove_lazy));
380 } 367 }
381 368
382 event_filter.RemoveEventMatcher(matcher_id); 369 event_filter.RemoveEventMatcher(matcher_id);
383 attached_matcher_ids_.erase(matcher_id); 370 attached_matcher_ids_.erase(matcher_id);
384 } 371 }
385 372
373 void EventBindings::MatchAgainstEventFilter(
374 const v8::FunctionCallbackInfo<v8::Value>& args) {
375 v8::Isolate* isolate = args.GetIsolate();
376 typedef std::set<EventFilter::MatcherID> MatcherIDs;
377 EventFilter& event_filter = g_event_filter.Get();
378 std::string event_name = *v8::String::Utf8Value(args[0]);
379 EventFilteringInfo info =
380 ParseFromObject(args[1]->ToObject(isolate), isolate);
381 // Only match events routed to this context's RenderFrame or ones that don't
382 // have a routingId in their filter.
383 MatcherIDs matched_event_filters = event_filter.MatchEvent(
384 event_name, info, context()->GetRenderFrame()->GetRoutingID());
385 v8::Local<v8::Array> array(
386 v8::Array::New(isolate, matched_event_filters.size()));
387 int i = 0;
388 for (MatcherIDs::iterator it = matched_event_filters.begin();
389 it != matched_event_filters.end();
390 ++it) {
391 array->Set(v8::Integer::New(isolate, i++), v8::Integer::New(isolate, *it));
392 }
393 args.GetReturnValue().Set(array);
394 }
395
386 void EventBindings::AttachUnmanagedEvent( 396 void EventBindings::AttachUnmanagedEvent(
387 const v8::FunctionCallbackInfo<v8::Value>& args) { 397 const v8::FunctionCallbackInfo<v8::Value>& args) {
388 v8::Isolate* isolate = args.GetIsolate(); 398 v8::Isolate* isolate = args.GetIsolate();
389 v8::HandleScope handle_scope(isolate); 399 v8::HandleScope handle_scope(isolate);
390 CHECK_EQ(1, args.Length()); 400 CHECK_EQ(1, args.Length());
391 CHECK(args[0]->IsString()); 401 CHECK(args[0]->IsString());
392 std::string event_name = gin::V8ToString(args[0]); 402 std::string event_name = gin::V8ToString(args[0]);
393 g_unmanaged_listeners.Get()[context()].insert(event_name); 403 g_unmanaged_listeners.Get()[context()].insert(event_name);
394 } 404 }
395 405
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 for (int matcher_id : attached_matcher_ids_safe) { 444 for (int matcher_id : attached_matcher_ids_safe) {
435 DetachFilteredEvent(matcher_id, false /* is_manual */); 445 DetachFilteredEvent(matcher_id, false /* is_manual */);
436 } 446 }
437 DCHECK(attached_matcher_ids_.empty()) 447 DCHECK(attached_matcher_ids_.empty())
438 << "Filtered events cannot be attached during invalidation"; 448 << "Filtered events cannot be attached during invalidation";
439 449
440 g_unmanaged_listeners.Get().erase(context()); 450 g_unmanaged_listeners.Get().erase(context());
441 } 451 }
442 452
443 } // namespace extensions 453 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/event_bindings.h ('k') | extensions/renderer/js_extension_bindings_system.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698