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

Side by Side Diff: chrome/browser/extensions/extension_event_router.cc

Issue 10696208: Move ExtensionEventRouter and related into extensions namespace (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fixed bug + latest master Created 8 years, 5 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 (c) 2012 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 "chrome/browser/extensions/extension_event_router.h"
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/message_loop.h"
10 #include "base/values.h"
11 #include "chrome/browser/extensions/api/runtime/runtime_api.h"
12 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
13 #include "chrome/browser/extensions/extension_devtools_manager.h"
14 #include "chrome/browser/extensions/extension_host.h"
15 #include "chrome/browser/extensions/extension_process_manager.h"
16 #include "chrome/browser/extensions/extension_processes_api.h"
17 #include "chrome/browser/extensions/extension_processes_api_constants.h"
18 #include "chrome/browser/extensions/extension_service.h"
19 #include "chrome/browser/extensions/extension_system.h"
20 #include "chrome/browser/extensions/lazy_background_task_queue.h"
21 #include "chrome/browser/extensions/process_map.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/common/chrome_notification_types.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/extensions/extension.h"
26 #include "chrome/common/extensions/extension_messages.h"
27 #include "chrome/common/extensions/api/extension_api.h"
28 #include "chrome/common/view_type.h"
29 #include "content/public/browser/notification_service.h"
30 #include "content/public/browser/render_process_host.h"
31
32 using base::Value;
33 using content::BrowserThread;
34 using extensions::Extension;
35 using extensions::ExtensionAPI;
36
37 namespace {
38
39 const char kDispatchEvent[] = "Event.dispatchJSON";
40
41 void NotifyEventListenerRemovedOnIOThread(
42 void* profile,
43 const std::string& extension_id,
44 const std::string& sub_event_name) {
45 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener(
46 profile, extension_id, sub_event_name);
47 }
48
49 } // namespace
50
51 struct ExtensionEventRouter::ListenerProcess {
52 content::RenderProcessHost* process;
53 std::string extension_id;
54
55 ListenerProcess(content::RenderProcessHost* process,
56 const std::string& extension_id)
57 : process(process), extension_id(extension_id) {}
58
59 bool operator<(const ListenerProcess& that) const {
60 if (process < that.process)
61 return true;
62 if (process == that.process && extension_id < that.extension_id)
63 return true;
64 return false;
65 }
66 };
67
68 // static
69 void ExtensionEventRouter::DispatchEvent(
70 IPC::Sender* ipc_sender,
71 const std::string& extension_id,
72 const std::string& event_name,
73 const Value& event_args,
74 const GURL& event_url,
75 UserGestureState user_gesture,
76 const extensions::EventFilteringInfo& info) {
77 // TODO(gdk): Reduce number of DeepCopy() calls throughout the event dispatch
78 // chain, starting by replacing the event_args with a Value*.
79 ListValue args;
80 args.Set(0, Value::CreateStringValue(event_name));
81 args.Set(1, event_args.DeepCopy());
82 args.Set(2, info.AsValue().release());
83
84 ipc_sender->Send(new ExtensionMsg_MessageInvoke(MSG_ROUTING_CONTROL,
85 extension_id, kDispatchEvent, args, event_url,
86 user_gesture == USER_GESTURE_ENABLED));
87 }
88
89 // static
90 void ExtensionEventRouter::DispatchEvent(
91 IPC::Sender* ipc_sender,
92 const std::string& extension_id,
93 const std::string& event_name,
94 const std::string& event_args,
95 const GURL& event_url,
96 UserGestureState user_gesture,
97 const extensions::EventFilteringInfo& info) {
98 scoped_ptr<Value> event_args_value(Value::CreateStringValue(event_args));
99 DispatchEvent(ipc_sender, extension_id, event_name, *event_args_value.get(),
100 event_url, user_gesture, info);
101 }
102
103 ExtensionEventRouter::ExtensionEventRouter(Profile* profile)
104 : profile_(profile),
105 extension_devtools_manager_(
106 extensions::ExtensionSystem::Get(profile)->devtools_manager()),
107 listeners_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
108 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
109 content::NotificationService::AllSources());
110 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
111 content::NotificationService::AllSources());
112 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
113 content::Source<Profile>(profile_));
114 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
115 content::Source<Profile>(profile_));
116 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
117 content::Source<Profile>(profile_));
118 }
119
120 ExtensionEventRouter::~ExtensionEventRouter() {}
121
122 void ExtensionEventRouter::AddEventListener(
123 const std::string& event_name,
124 content::RenderProcessHost* process,
125 const std::string& extension_id) {
126 listeners_.AddListener(scoped_ptr<EventListener>(new EventListener(
127 event_name, extension_id, process, scoped_ptr<DictionaryValue>())));
128 }
129
130 void ExtensionEventRouter::RemoveEventListener(
131 const std::string& event_name,
132 content::RenderProcessHost* process,
133 const std::string& extension_id) {
134 EventListener listener(event_name, extension_id, process,
135 scoped_ptr<DictionaryValue>());
136 listeners_.RemoveListener(&listener);
137 }
138
139 void ExtensionEventRouter::OnListenerAdded(const EventListener* listener) {
140 // We don't care about lazy events being added.
141 if (!listener->process)
142 return;
143
144 if (extension_devtools_manager_.get())
145 extension_devtools_manager_->AddEventListener(listener->event_name,
146 listener->process->GetID());
147
148 // We lazily tell the TaskManager to start updating when listeners to the
149 // processes.onUpdated or processes.onUpdatedWithMemory events arrive.
150 const std::string& event_name = listener->event_name;
151 if (event_name.compare(extension_processes_api_constants::kOnUpdated) == 0 ||
152 event_name.compare(
153 extension_processes_api_constants::kOnUpdatedWithMemory) == 0)
154 ExtensionProcessesEventRouter::GetInstance()->ListenerAdded();
155 }
156
157 void ExtensionEventRouter::OnListenerRemoved(const EventListener* listener) {
158 // We don't care about lazy events being removed.
159 if (!listener->process)
160 return;
161
162 const std::string& event_name = listener->event_name;
163 if (extension_devtools_manager_.get())
164 extension_devtools_manager_->RemoveEventListener(
165 event_name, listener->process->GetID());
166
167 // If a processes.onUpdated or processes.onUpdatedWithMemory event listener
168 // is removed (or a process with one exits), then we let the extension API
169 // know that it has one fewer listener.
170 if (event_name.compare(extension_processes_api_constants::kOnUpdated) == 0 ||
171 event_name.compare(
172 extension_processes_api_constants::kOnUpdatedWithMemory) == 0)
173 ExtensionProcessesEventRouter::GetInstance()->ListenerRemoved();
174
175 BrowserThread::PostTask(
176 BrowserThread::IO, FROM_HERE,
177 base::Bind(
178 &NotifyEventListenerRemovedOnIOThread,
179 profile_, listener->extension_id, listener->event_name));
180 }
181
182 void ExtensionEventRouter::AddLazyEventListener(
183 const std::string& event_name,
184 const std::string& extension_id) {
185 scoped_ptr<EventListener> listener(new EventListener(
186 event_name, extension_id, NULL, scoped_ptr<DictionaryValue>()));
187 bool is_new = listeners_.AddListener(listener.Pass());
188
189 if (is_new) {
190 extensions::ExtensionPrefs* prefs =
191 profile_->GetExtensionService()->extension_prefs();
192 std::set<std::string> events = prefs->GetRegisteredEvents(extension_id);
193 bool prefs_is_new = events.insert(event_name).second;
194 if (prefs_is_new)
195 prefs->SetRegisteredEvents(extension_id, events);
196 }
197 }
198
199 void ExtensionEventRouter::RemoveLazyEventListener(
200 const std::string& event_name,
201 const std::string& extension_id) {
202 EventListener listener(event_name, extension_id, NULL,
203 scoped_ptr<DictionaryValue>());
204 bool did_exist = listeners_.RemoveListener(&listener);
205
206 if (did_exist) {
207 extensions::ExtensionPrefs* prefs =
208 profile_->GetExtensionService()->extension_prefs();
209 std::set<std::string> events = prefs->GetRegisteredEvents(extension_id);
210 bool prefs_did_exist = events.erase(event_name) > 0;
211 DCHECK(prefs_did_exist);
212 prefs->SetRegisteredEvents(extension_id, events);
213 }
214 }
215
216 void ExtensionEventRouter::AddFilteredEventListener(
217 const std::string& event_name,
218 content::RenderProcessHost* process,
219 const std::string& extension_id,
220 const base::DictionaryValue& filter,
221 bool add_lazy_listener) {
222 listeners_.AddListener(scoped_ptr<EventListener>(new EventListener(
223 event_name, extension_id, process,
224 scoped_ptr<DictionaryValue>(filter.DeepCopy()))));
225
226 if (add_lazy_listener) {
227 bool added = listeners_.AddListener(scoped_ptr<EventListener>(
228 new EventListener(event_name, extension_id, NULL,
229 scoped_ptr<DictionaryValue>(filter.DeepCopy()))));
230
231 if (added) {
232 extensions::ExtensionPrefs* prefs =
233 profile_->GetExtensionService()->extension_prefs();
234 prefs->AddFilterToEvent(event_name, extension_id, &filter);
235 }
236 }
237 }
238
239 void ExtensionEventRouter::RemoveFilteredEventListener(
240 const std::string& event_name,
241 content::RenderProcessHost* process,
242 const std::string& extension_id,
243 const base::DictionaryValue& filter,
244 bool remove_lazy_listener) {
245 EventListener listener(event_name, extension_id, process,
246 scoped_ptr<DictionaryValue>(filter.DeepCopy()));
247
248 listeners_.RemoveListener(&listener);
249
250 if (remove_lazy_listener) {
251 listener.process = NULL;
252 bool removed = listeners_.RemoveListener(&listener);
253
254 if (removed) {
255 extensions::ExtensionPrefs* prefs =
256 profile_->GetExtensionService()->extension_prefs();
257 prefs->RemoveFilterFromEvent(event_name, extension_id, &filter);
258 }
259 }
260 }
261
262 bool ExtensionEventRouter::HasEventListener(const std::string& event_name) {
263 return listeners_.HasListenerForEvent(event_name);
264 }
265
266 bool ExtensionEventRouter::ExtensionHasEventListener(
267 const std::string& extension_id, const std::string& event_name) {
268 return listeners_.HasListenerForExtension(extension_id, event_name);
269 }
270
271 bool ExtensionEventRouter::HasEventListenerImpl(
272 const ListenerMap& listener_map,
273 const std::string& extension_id,
274 const std::string& event_name) {
275 ListenerMap::const_iterator it = listener_map.find(event_name);
276 if (it == listener_map.end())
277 return false;
278
279 const std::set<ListenerProcess>& listeners = it->second;
280 if (extension_id.empty())
281 return !listeners.empty();
282
283 for (std::set<ListenerProcess>::const_iterator listener = listeners.begin();
284 listener != listeners.end(); ++listener) {
285 if (listener->extension_id == extension_id)
286 return true;
287 }
288 return false;
289 }
290
291 void ExtensionEventRouter::DispatchEventToRenderers(
292 const std::string& event_name,
293 const std::string& event_args,
294 Profile* restrict_to_profile,
295 const GURL& event_url,
296 extensions::EventFilteringInfo info) {
297 DCHECK(!event_args.empty());
298 StringValue event_args_value(event_args);
299 linked_ptr<ExtensionEvent> event(
300 new ExtensionEvent(event_name, event_args_value, event_url,
301 restrict_to_profile, USER_GESTURE_UNKNOWN, info));
302 DispatchEventImpl("", event);
303 }
304
305 void ExtensionEventRouter::DispatchEventToRenderers(
306 const std::string& event_name,
307 const std::string& event_args,
308 Profile* restrict_to_profile,
309 const GURL& event_url) {
310 DispatchEventToRenderers(event_name, event_args, restrict_to_profile,
311 event_url, extensions::EventFilteringInfo());
312 }
313
314 void ExtensionEventRouter::DispatchEventToExtension(
315 const std::string& extension_id,
316 const std::string& event_name,
317 const Value& event_args,
318 Profile* restrict_to_profile,
319 const GURL& event_url) {
320 DCHECK(!extension_id.empty());
321 linked_ptr<ExtensionEvent> event(
322 new ExtensionEvent(event_name, event_args, event_url,
323 restrict_to_profile, USER_GESTURE_UNKNOWN,
324 EventFilteringInfo()));
325 DispatchEventImpl(extension_id, event);
326 }
327
328 void ExtensionEventRouter::DispatchEventToExtension(
329 const std::string& extension_id,
330 const std::string& event_name,
331 const std::string& event_args,
332 Profile* restrict_to_profile,
333 const GURL& event_url) {
334 StringValue event_args_value(event_args);
335 DispatchEventToExtension(extension_id, event_name, event_args_value,
336 restrict_to_profile, event_url);
337 }
338
339 void ExtensionEventRouter::DispatchEventToExtension(
340 const std::string& extension_id,
341 const std::string& event_name,
342 const std::string& event_args,
343 Profile* restrict_to_profile,
344 const GURL& event_url,
345 UserGestureState user_gesture) {
346 DCHECK(!extension_id.empty());
347 StringValue event_args_value(event_args);
348 linked_ptr<ExtensionEvent> event(
349 new ExtensionEvent(event_name, event_args_value, event_url,
350 restrict_to_profile, user_gesture,
351 EventFilteringInfo()));
352 DispatchEventImpl(extension_id, event);
353 }
354
355 void ExtensionEventRouter::DispatchEventsToRenderersAcrossIncognito(
356 const std::string& event_name,
357 const std::string& event_args,
358 Profile* restrict_to_profile,
359 const std::string& cross_incognito_args,
360 const GURL& event_url) {
361 linked_ptr<ExtensionEvent> event(
362 new ExtensionEvent(event_name, event_args, event_url,
363 restrict_to_profile, cross_incognito_args,
364 USER_GESTURE_UNKNOWN, EventFilteringInfo()));
365 DispatchEventImpl("", event);
366 }
367
368 void ExtensionEventRouter::DispatchEventImpl(
369 const std::string& restrict_to_extension_id,
370 const linked_ptr<ExtensionEvent>& event) {
371 // We don't expect to get events from a completely different profile.
372 DCHECK(!event->restrict_to_profile ||
373 profile_->IsSameProfile(event->restrict_to_profile));
374
375 std::set<const EventListener*> listeners(
376 listeners_.GetEventListeners(*event));
377 for (std::set<const EventListener*>::iterator it = listeners.begin();
378 it != listeners.end(); it++) {
379 const EventListener* listener = *it;
380 if (restrict_to_extension_id.empty() ||
381 restrict_to_extension_id == listener->extension_id) {
382 if (listener->process) {
383 DispatchEventToProcess(listener->extension_id, listener->process,
384 event);
385 } else {
386 DispatchLazyEvent(listener->extension_id, event);
387 }
388 }
389 }
390 }
391
392 void ExtensionEventRouter::DispatchLazyEvent(
393 const std::string& extension_id,
394 const linked_ptr<ExtensionEvent>& event) {
395 ExtensionService* service = profile_->GetExtensionService();
396 // Check both the original and the incognito profile to see if we
397 // should load a lazy bg page to handle the event. The latter case
398 // occurs in the case of split-mode extensions.
399 const Extension* extension = service->extensions()->GetByID(extension_id);
400 if (extension) {
401 MaybeLoadLazyBackgroundPageToDispatchEvent(profile_, extension, event);
402 if (profile_->HasOffTheRecordProfile() &&
403 extension->incognito_split_mode()) {
404 MaybeLoadLazyBackgroundPageToDispatchEvent(
405 profile_->GetOffTheRecordProfile(), extension, event);
406 }
407 }
408 }
409
410 void ExtensionEventRouter::DispatchEventToProcess(
411 const std::string& extension_id,
412 content::RenderProcessHost* process,
413 const linked_ptr<ExtensionEvent>& event) {
414 ExtensionService* service = profile_->GetExtensionService();
415 const Extension* extension = service->extensions()->GetByID(extension_id);
416
417 // The extension could have been removed, but we do not unregister it until
418 // the extension process is unloaded.
419 if (!extension)
420 return;
421
422 Profile* listener_profile = Profile::FromBrowserContext(
423 process->GetBrowserContext());
424 extensions::ProcessMap* process_map =
425 listener_profile->GetExtensionService()->process_map();
426 // If the event is privileged, only send to extension processes. Otherwise,
427 // it's OK to send to normal renderers (e.g., for content scripts).
428 if (ExtensionAPI::GetSharedInstance()->IsPrivileged(event->event_name) &&
429 !process_map->Contains(extension->id(), process->GetID())) {
430 return;
431 }
432
433 const Value* event_args = NULL;
434 if (!CanDispatchEventToProfile(listener_profile, extension,
435 event, &event_args)) {
436 return;
437 }
438
439 DispatchEvent(process, extension_id,
440 event->event_name, *event_args,
441 event->event_url, event->user_gesture,
442 event->info);
443 IncrementInFlightEvents(listener_profile, extension);
444 }
445
446 bool ExtensionEventRouter::CanDispatchEventToProfile(
447 Profile* profile,
448 const Extension* extension,
449 const linked_ptr<ExtensionEvent>& event,
450 const Value** event_args) {
451 *event_args = event->event_args.get();
452
453 // Is this event from a different profile than the renderer (ie, an
454 // incognito tab event sent to a normal process, or vice versa).
455 bool cross_incognito = event->restrict_to_profile &&
456 profile != event->restrict_to_profile;
457 if (cross_incognito &&
458 !profile->GetExtensionService()->CanCrossIncognito(extension)) {
459 if (!event->cross_incognito_args.get())
460 return false;
461 // Send the event with different arguments to extensions that can't
462 // cross incognito.
463 *event_args = event->cross_incognito_args.get();
464 }
465
466 return true;
467 }
468
469 void ExtensionEventRouter::MaybeLoadLazyBackgroundPageToDispatchEvent(
470 Profile* profile,
471 const Extension* extension,
472 const linked_ptr<ExtensionEvent>& event) {
473 const Value* event_args = NULL;
474 if (!CanDispatchEventToProfile(profile, extension, event, &event_args))
475 return;
476
477 extensions::LazyBackgroundTaskQueue* queue =
478 extensions::ExtensionSystem::Get(profile)->lazy_background_task_queue();
479 if (queue->ShouldEnqueueTask(profile, extension)) {
480 queue->AddPendingTask(
481 profile, extension->id(),
482 base::Bind(&ExtensionEventRouter::DispatchPendingEvent,
483 base::Unretained(this), event));
484 }
485 }
486
487 void ExtensionEventRouter::IncrementInFlightEvents(
488 Profile* profile, const Extension* extension) {
489 // Only increment in-flight events if the lazy background page is active,
490 // because that's the only time we'll get an ACK.
491 if (extension->has_lazy_background_page()) {
492 ExtensionProcessManager* pm =
493 extensions::ExtensionSystem::Get(profile)->process_manager();
494 ExtensionHost* host = pm->GetBackgroundHostForExtension(extension->id());
495 if (host)
496 pm->IncrementLazyKeepaliveCount(extension);
497 }
498 }
499
500 void ExtensionEventRouter::OnEventAck(
501 Profile* profile, const std::string& extension_id) {
502 ExtensionProcessManager* pm =
503 extensions::ExtensionSystem::Get(profile)->process_manager();
504 ExtensionHost* host = pm->GetBackgroundHostForExtension(extension_id);
505 // The event ACK is routed to the background host, so this should never be
506 // NULL.
507 CHECK(host);
508 // TODO(mpcomplete): We should never get this message unless
509 // has_lazy_background_page is true. Find out why we're getting it anyway.
510 if (host->extension() && host->extension()->has_lazy_background_page())
511 pm->DecrementLazyKeepaliveCount(host->extension());
512 }
513
514 void ExtensionEventRouter::DispatchPendingEvent(
515 const linked_ptr<ExtensionEvent>& event,
516 ExtensionHost* host) {
517 if (!host)
518 return;
519
520 if (listeners_.HasProcessListener(host->render_process_host(),
521 host->extension()->id()))
522 DispatchEventToProcess(host->extension()->id(),
523 host->render_process_host(), event);
524 }
525
526 void ExtensionEventRouter::Observe(
527 int type,
528 const content::NotificationSource& source,
529 const content::NotificationDetails& details) {
530 switch (type) {
531 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED:
532 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
533 content::RenderProcessHost* renderer =
534 content::Source<content::RenderProcessHost>(source).ptr();
535 // Remove all event listeners associated with this renderer.
536 listeners_.RemoveListenersForProcess(renderer);
537 break;
538 }
539 case chrome::NOTIFICATION_EXTENSION_LOADED: {
540 // Add all registered lazy listeners to our cache.
541 const Extension* extension =
542 content::Details<const Extension>(details).ptr();
543 extensions::ExtensionPrefs* prefs =
544 profile_->GetExtensionService()->extension_prefs();
545 std::set<std::string> registered_events =
546 prefs->GetRegisteredEvents(extension->id());
547 listeners_.LoadUnfilteredLazyListeners(extension->id(),
548 registered_events);
549 const DictionaryValue* filtered_events =
550 prefs->GetFilteredEvents(extension->id());
551 if (filtered_events)
552 listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events);
553 break;
554 }
555 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
556 // Remove all registered lazy listeners from our cache.
557 extensions::UnloadedExtensionInfo* unloaded =
558 content::Details<extensions::UnloadedExtensionInfo>(details).ptr();
559 listeners_.RemoveLazyListenersForExtension(unloaded->extension->id());
560 break;
561 }
562 case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
563 // Dispatch the onInstalled event.
564 const Extension* extension =
565 content::Details<const Extension>(details).ptr();
566 MessageLoop::current()->PostTask(FROM_HERE,
567 base::Bind(&extensions::RuntimeEventRouter::DispatchOnInstalledEvent,
568 profile_, extension->id()));
569 break;
570 }
571 default:
572 NOTREACHED();
573 return;
574 }
575 }
576
577 ExtensionEvent::ExtensionEvent(
578 const std::string& event_name,
579 const Value& event_args,
580 const GURL& event_url,
581 Profile* restrict_to_profile,
582 const Value& cross_incognito_args,
583 ExtensionEventRouter::UserGestureState user_gesture,
584 const extensions::EventFilteringInfo& info)
585 : event_name(event_name),
586 event_args(event_args.DeepCopy()),
587 event_url(event_url),
588 restrict_to_profile(restrict_to_profile),
589 cross_incognito_args(cross_incognito_args.DeepCopy()),
590 user_gesture(user_gesture),
591 info(info) {
592 }
593
594 ExtensionEvent::ExtensionEvent(
595 const std::string& event_name,
596 const std::string& event_args,
597 const GURL& event_url,
598 Profile* restrict_to_profile,
599 const std::string& cross_incognito_args,
600 ExtensionEventRouter::UserGestureState user_gesture,
601 const extensions::EventFilteringInfo& info)
602 : event_name(event_name),
603 event_args(Value::CreateStringValue(event_args)),
604 event_url(event_url),
605 restrict_to_profile(restrict_to_profile),
606 cross_incognito_args(Value::CreateStringValue(cross_incognito_args)),
607 user_gesture(user_gesture),
608 info(info) {
609 }
610
611 ExtensionEvent::ExtensionEvent(
612 const std::string& event_name,
613 const Value& event_args,
614 const GURL& event_url,
615 Profile* restrict_to_profile,
616 ExtensionEventRouter::UserGestureState user_gesture,
617 const extensions::EventFilteringInfo& info)
618 : event_name(event_name),
619 event_args(event_args.DeepCopy()),
620 event_url(event_url),
621 restrict_to_profile(restrict_to_profile),
622 cross_incognito_args(NULL),
623 user_gesture(user_gesture),
624 info(info) {
625 }
626
627 ExtensionEvent::~ExtensionEvent() {
628 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_event_router.h ('k') | chrome/browser/extensions/extension_event_router_forwarder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698