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

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

Issue 2909673003: [Extensions Bindings] Request JS execution from messaging bindings (Closed)
Patch Set: lazyboy's 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
« no previous file with comments | « extensions/renderer/event_bindings.h ('k') | extensions/renderer/event_emitter.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 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/value_counter.h" 25 #include "extensions/common/value_counter.h"
26 #include "extensions/renderer/extension_frame_helper.h" 26 #include "extensions/renderer/extension_frame_helper.h"
27 #include "extensions/renderer/script_context.h" 27 #include "extensions/renderer/script_context.h"
28 #include "extensions/renderer/service_worker_request_sender.h" 28 #include "extensions/renderer/service_worker_request_sender.h"
29 #include "extensions/renderer/worker_thread_dispatcher.h" 29 #include "extensions/renderer/worker_thread_dispatcher.h"
30 #include "gin/converter.h"
30 #include "url/gurl.h" 31 #include "url/gurl.h"
31 32
32 namespace extensions { 33 namespace extensions {
33 34
34 namespace { 35 namespace {
35 36
36 // A map of event names to the number of contexts listening to that event. 37 // A map of event names to the number of contexts listening to that event.
37 // We notify the browser about event listeners when we transition between 0 38 // We notify the browser about event listeners when we transition between 0
38 // and 1. 39 // and 1.
39 typedef std::map<std::string, int> EventListenerCounts; 40 typedef std::map<std::string, int> EventListenerCounts;
40 41
41 // A map of extension IDs to listener counts for that extension. 42 // A map of extension IDs to listener counts for that extension.
42 base::LazyInstance<std::map<std::string, EventListenerCounts>>::DestructorAtExit 43 base::LazyInstance<std::map<std::string, EventListenerCounts>>::DestructorAtExit
43 g_listener_counts = LAZY_INSTANCE_INITIALIZER; 44 g_listener_counts = LAZY_INSTANCE_INITIALIZER;
44 45
46 // A collection of the unmanaged events (i.e., those for which the browser is
47 // not notified of changes) that have listeners, by context.
48 base::LazyInstance<std::map<ScriptContext*, std::set<std::string>>>::Leaky
49 g_unmanaged_listeners = LAZY_INSTANCE_INITIALIZER;
50
45 // A map of (extension ID, event name) pairs to the filtered listener counts 51 // A map of (extension ID, event name) pairs to the filtered listener counts
46 // for that pair. The map is used to keep track of which filters are in effect 52 // for that pair. The map is used to keep track of which filters are in effect
47 // for which events. We notify the browser about filtered event listeners when 53 // for which events. We notify the browser about filtered event listeners when
48 // we transition between 0 and 1. 54 // we transition between 0 and 1.
49 using FilteredEventListenerKey = std::pair<std::string, std::string>; 55 using FilteredEventListenerKey = std::pair<std::string, std::string>;
50 using FilteredEventListenerCounts = 56 using FilteredEventListenerCounts =
51 std::map<FilteredEventListenerKey, std::unique_ptr<ValueCounter>>; 57 std::map<FilteredEventListenerKey, std::unique_ptr<ValueCounter>>;
52 base::LazyInstance<FilteredEventListenerCounts>::DestructorAtExit 58 base::LazyInstance<FilteredEventListenerCounts>::DestructorAtExit
53 g_filtered_listener_counts = LAZY_INSTANCE_INITIALIZER; 59 g_filtered_listener_counts = LAZY_INSTANCE_INITIALIZER;
54 60
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 base::Unretained(this))); 173 base::Unretained(this)));
168 RouteFunction( 174 RouteFunction(
169 "AttachFilteredEvent", 175 "AttachFilteredEvent",
170 base::Bind(&EventBindings::AttachFilteredEvent, base::Unretained(this))); 176 base::Bind(&EventBindings::AttachFilteredEvent, base::Unretained(this)));
171 RouteFunction("DetachFilteredEvent", 177 RouteFunction("DetachFilteredEvent",
172 base::Bind(&EventBindings::DetachFilteredEventHandler, 178 base::Bind(&EventBindings::DetachFilteredEventHandler,
173 base::Unretained(this))); 179 base::Unretained(this)));
174 RouteFunction("MatchAgainstEventFilter", 180 RouteFunction("MatchAgainstEventFilter",
175 base::Bind(&EventBindings::MatchAgainstEventFilter, 181 base::Bind(&EventBindings::MatchAgainstEventFilter,
176 base::Unretained(this))); 182 base::Unretained(this)));
183 RouteFunction(
184 "AttachUnmanagedEvent",
185 base::Bind(&EventBindings::AttachUnmanagedEvent, base::Unretained(this)));
186 RouteFunction(
187 "DetachUnmanagedEvent",
188 base::Bind(&EventBindings::DetachUnmanagedEvent, base::Unretained(this)));
177 189
178 // 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
179 // outlive us. 191 // outlive us.
180 context->AddInvalidationObserver( 192 context->AddInvalidationObserver(
181 base::Bind(&EventBindings::OnInvalidated, base::Unretained(this))); 193 base::Bind(&EventBindings::OnInvalidated, base::Unretained(this)));
182 } 194 }
183 195
184 EventBindings::~EventBindings() {} 196 EventBindings::~EventBindings() {}
185 197
198 bool EventBindings::HasListener(ScriptContext* script_context,
199 const std::string& event_name) {
200 const auto& unmanaged_listeners = g_unmanaged_listeners.Get();
201 auto unmanaged_iter = unmanaged_listeners.find(script_context);
202 if (unmanaged_iter != unmanaged_listeners.end() &&
203 base::ContainsKey(unmanaged_iter->second, event_name)) {
204 return true;
205 }
206 const auto& managed_listeners = g_listener_counts.Get();
207 auto managed_iter =
208 managed_listeners.find(GetKeyForScriptContext(script_context));
209 if (managed_iter != managed_listeners.end()) {
210 auto event_iter = managed_iter->second.find(event_name);
211 if (event_iter != managed_iter->second.end() && event_iter->second > 0) {
212 return true;
213 }
214 }
215
216 return false;
217 }
218
186 void EventBindings::AttachEventHandler( 219 void EventBindings::AttachEventHandler(
187 const v8::FunctionCallbackInfo<v8::Value>& args) { 220 const v8::FunctionCallbackInfo<v8::Value>& args) {
188 CHECK_EQ(1, args.Length()); 221 CHECK_EQ(1, args.Length());
189 CHECK(args[0]->IsString()); 222 CHECK(args[0]->IsString());
190 AttachEvent(*v8::String::Utf8Value(args[0])); 223 AttachEvent(*v8::String::Utf8Value(args[0]));
191 } 224 }
192 225
193 void EventBindings::AttachEvent(const std::string& event_name) { 226 void EventBindings::AttachEvent(const std::string& event_name) {
194 if (!context()->HasAccessOrThrowError(event_name)) 227 if (!context()->HasAccessOrThrowError(event_name))
195 return; 228 return;
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 v8::Array::New(isolate, matched_event_filters.size())); 386 v8::Array::New(isolate, matched_event_filters.size()));
354 int i = 0; 387 int i = 0;
355 for (MatcherIDs::iterator it = matched_event_filters.begin(); 388 for (MatcherIDs::iterator it = matched_event_filters.begin();
356 it != matched_event_filters.end(); 389 it != matched_event_filters.end();
357 ++it) { 390 ++it) {
358 array->Set(v8::Integer::New(isolate, i++), v8::Integer::New(isolate, *it)); 391 array->Set(v8::Integer::New(isolate, i++), v8::Integer::New(isolate, *it));
359 } 392 }
360 args.GetReturnValue().Set(array); 393 args.GetReturnValue().Set(array);
361 } 394 }
362 395
396 void EventBindings::AttachUnmanagedEvent(
397 const v8::FunctionCallbackInfo<v8::Value>& args) {
398 v8::Isolate* isolate = args.GetIsolate();
399 v8::HandleScope handle_scope(isolate);
400 CHECK_EQ(1, args.Length());
401 CHECK(args[0]->IsString());
402 std::string event_name = gin::V8ToString(args[0]);
403 g_unmanaged_listeners.Get()[context()].insert(event_name);
404 }
405
406 void EventBindings::DetachUnmanagedEvent(
407 const v8::FunctionCallbackInfo<v8::Value>& args) {
408 v8::Isolate* isolate = args.GetIsolate();
409 v8::HandleScope handle_scope(isolate);
410 CHECK_EQ(1, args.Length());
411 CHECK(args[0]->IsString());
412 std::string event_name = gin::V8ToString(args[0]);
413 g_unmanaged_listeners.Get()[context()].erase(event_name);
414 }
415
363 std::unique_ptr<EventMatcher> EventBindings::ParseEventMatcher( 416 std::unique_ptr<EventMatcher> EventBindings::ParseEventMatcher(
364 std::unique_ptr<base::DictionaryValue> filter) { 417 std::unique_ptr<base::DictionaryValue> filter) {
365 return base::MakeUnique<EventMatcher>( 418 return base::MakeUnique<EventMatcher>(
366 std::move(filter), context()->GetRenderFrame()->GetRoutingID()); 419 std::move(filter), context()->GetRenderFrame()->GetRoutingID());
367 } 420 }
368 421
369 IPC::Sender* EventBindings::GetIPCSender() { 422 IPC::Sender* EventBindings::GetIPCSender() {
370 const bool is_service_worker_context = 423 const bool is_service_worker_context =
371 context()->context_type() == Feature::SERVICE_WORKER_CONTEXT; 424 context()->context_type() == Feature::SERVICE_WORKER_CONTEXT;
372 DCHECK_EQ(is_service_worker_context, 425 DCHECK_EQ(is_service_worker_context,
(...skipping 13 matching lines...) Expand all
386 DCHECK(attached_event_names_.empty()) 439 DCHECK(attached_event_names_.empty())
387 << "Events cannot be attached during invalidation"; 440 << "Events cannot be attached during invalidation";
388 441
389 // Same for filtered events. 442 // Same for filtered events.
390 std::set<int> attached_matcher_ids_safe = attached_matcher_ids_; 443 std::set<int> attached_matcher_ids_safe = attached_matcher_ids_;
391 for (int matcher_id : attached_matcher_ids_safe) { 444 for (int matcher_id : attached_matcher_ids_safe) {
392 DetachFilteredEvent(matcher_id, false /* is_manual */); 445 DetachFilteredEvent(matcher_id, false /* is_manual */);
393 } 446 }
394 DCHECK(attached_matcher_ids_.empty()) 447 DCHECK(attached_matcher_ids_.empty())
395 << "Filtered events cannot be attached during invalidation"; 448 << "Filtered events cannot be attached during invalidation";
449
450 g_unmanaged_listeners.Get().erase(context());
396 } 451 }
397 452
398 } // namespace extensions 453 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/event_bindings.h ('k') | extensions/renderer/event_emitter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698