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

Side by Side Diff: extensions/browser/events/lazy_event_dispatcher.cc

Issue 2940883007: Move lazy event dispatching code out of EventRouter. (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
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "extensions/browser/events/lazy_event_dispatcher.h"
6
7 #include "base/bind.h"
8 #include "base/memory/ptr_util.h"
9 #include "extensions/browser/event_router.h"
10 #include "extensions/browser/extension_registry.h"
11 #include "extensions/browser/extensions_browser_client.h"
12 #include "extensions/browser/lazy_background_task_queue.h"
13 #include "extensions/browser/lazy_context_id.h"
14 #include "extensions/common/manifest_handlers/incognito_info.h"
15
16 using content::BrowserContext;
17
18 namespace extensions {
19
20 LazyEventDispatcher::LazyEventDispatcher(BrowserContext* browser_context,
21 const linked_ptr<Event>& event,
22 const DispatchFunc& dispatch_func)
23 : browser_context_(browser_context),
24 event_(event),
25 dispatch_func_(dispatch_func) {}
26
27 LazyEventDispatcher::~LazyEventDispatcher() {}
28
29 void LazyEventDispatcher::DispatchToEventPage(
30 const ExtensionId& extension_id,
31 const base::DictionaryValue* listener_filter) {
32 LazyContextId dispatch_context(browser_context_, extension_id);
33 DispatchToLazyContext(&dispatch_context, listener_filter);
34 }
35
36 bool LazyEventDispatcher::HasAlreadyDispatched(
37 BrowserContext* context,
38 const EventListener* listener) const {
39 auto dispatch_context =
40 base::MakeUnique<LazyContextId>(context, listener->extension_id());
41 return HasAlreadyDispatchedImpl(dispatch_context.get());
42 }
43
44 void LazyEventDispatcher::DispatchToLazyContext(
45 LazyContextId* dispatch_context,
46 const base::DictionaryValue* listener_filter) {
47 const Extension* extension = ExtensionRegistry::Get(browser_context_)
48 ->enabled_extensions()
49 .GetByID(dispatch_context->extension_id());
50 if (!extension)
51 return;
52
53 // Check both the original and the incognito browser context to see if we
54 // should load a non-peristent context (a lazy background page or an
55 // extension service worker) to handle the event. The latter case
56 // occurs in the case of split-mode extensions.
57 if (QueueEventDispatch(dispatch_context, extension, listener_filter))
58 RecordAlreadyDispatched(dispatch_context);
59
60 BrowserContext* additional_context = GetIncognitoContext(extension);
61 if (!additional_context)
62 return;
63
64 dispatch_context->set_browser_context(additional_context);
65 if (QueueEventDispatch(dispatch_context, extension, listener_filter))
66 RecordAlreadyDispatched(dispatch_context);
67 }
68
69 bool LazyEventDispatcher::QueueEventDispatch(
70 LazyContextId* dispatch_context,
71 const Extension* extension,
72 const base::DictionaryValue* listener_filter) {
73 if (!EventRouter::CanDispatchEventToBrowserContext(
74 dispatch_context->browser_context(), extension, *event_)) {
75 return false;
76 }
77
78 if (HasAlreadyDispatchedImpl(dispatch_context))
79 return false;
80
81 LazyBackgroundTaskQueue* queue = dispatch_context->GetTaskQueue();
82 if (!queue->ShouldEnqueueTask(dispatch_context->browser_context(),
83 extension)) {
84 return false;
85 }
86
87 linked_ptr<Event> dispatched_event(event_);
88
89 // If there's a dispatch callback, call it now (rather than dispatch time)
90 // to avoid lifetime issues. Use a separate copy of the event args, so they
91 // last until the event is dispatched.
92 if (!event_->will_dispatch_callback.is_null()) {
93 dispatched_event.reset(event_->DeepCopy());
94 if (!dispatched_event->will_dispatch_callback.Run(
95 dispatch_context->browser_context(), extension,
96 dispatched_event.get(), listener_filter)) {
97 // The event has been canceled.
98 return true;
99 }
100 // Ensure we don't call it again at dispatch time.
101 dispatched_event->will_dispatch_callback.Reset();
102 }
103
104 queue->AddPendingTask(dispatch_context->browser_context(),
105 dispatch_context->extension_id(),
106 base::Bind(dispatch_func_, dispatched_event));
107
108 return true;
109 }
110
111 bool LazyEventDispatcher::HasAlreadyDispatchedImpl(
112 const LazyContextId* dispatch_context) const {
113 DCHECK(dispatch_context->is_for_event_page());
114 EventPageDispatchIdentifier dispatch_id(dispatch_context->browser_context(),
115 dispatch_context->extension_id());
116 return base::ContainsKey(dispatched_ep_ids_, dispatch_id);
117 }
118
119 void LazyEventDispatcher::RecordAlreadyDispatched(
120 LazyContextId* dispatch_context) {
121 DCHECK(dispatch_context->is_for_event_page());
122 dispatched_ep_ids_.insert(std::make_pair(dispatch_context->browser_context(),
123 dispatch_context->extension_id()));
124 }
125
126 BrowserContext* LazyEventDispatcher::GetIncognitoContext(
127 const Extension* extension) {
128 if (!IncognitoInfo::IsSplitMode(extension))
129 return nullptr;
130 ExtensionsBrowserClient* browser_client = ExtensionsBrowserClient::Get();
131 if (!browser_client->HasOffTheRecordContext(browser_context_))
132 return nullptr;
133 return browser_client->GetOffTheRecordContext(browser_context_);
134 }
135
136 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698