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

Side by Side Diff: extensions/browser/event_router.cc

Issue 1272373003: Add extension event histogram values for messaging, webRequest, and webview. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 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 (c) 2012 The Chromium Authors. All rights reserved. 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 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/browser/event_router.h" 5 #include "extensions/browser/event_router.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/atomic_sequence_num.h" 9 #include "base/atomic_sequence_num.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/lazy_instance.h" 12 #include "base/lazy_instance.h"
13 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
14 #include "base/stl_util.h" 14 #include "base/stl_util.h"
15 #include "base/values.h" 15 #include "base/values.h"
16 #include "content/public/browser/notification_service.h" 16 #include "content/public/browser/notification_service.h"
17 #include "content/public/browser/render_process_host.h" 17 #include "content/public/browser/render_process_host.h"
18 #include "extensions/browser/api_activity_monitor.h" 18 #include "extensions/browser/api_activity_monitor.h"
19 #include "extensions/browser/event_router_factory.h" 19 #include "extensions/browser/event_router_factory.h"
20 #include "extensions/browser/extension_host.h" 20 #include "extensions/browser/extension_host.h"
21 #include "extensions/browser/extension_prefs.h" 21 #include "extensions/browser/extension_prefs.h"
22 #include "extensions/browser/extension_registry.h" 22 #include "extensions/browser/extension_registry.h"
23 #include "extensions/browser/extension_system.h" 23 #include "extensions/browser/extension_system.h"
24 #include "extensions/browser/extensions_browser_client.h" 24 #include "extensions/browser/extensions_browser_client.h"
25 #include "extensions/browser/lazy_background_task_queue.h" 25 #include "extensions/browser/lazy_background_task_queue.h"
26 #include "extensions/browser/notification_types.h" 26 #include "extensions/browser/notification_types.h"
27 #include "extensions/browser/process_manager.h" 27 #include "extensions/browser/process_manager.h"
28 #include "extensions/browser/process_map.h" 28 #include "extensions/browser/process_map.h"
29 #include "extensions/common/constants.h"
29 #include "extensions/common/extension.h" 30 #include "extensions/common/extension.h"
30 #include "extensions/common/extension_api.h" 31 #include "extensions/common/extension_api.h"
31 #include "extensions/common/extension_messages.h" 32 #include "extensions/common/extension_messages.h"
32 #include "extensions/common/extension_urls.h" 33 #include "extensions/common/extension_urls.h"
33 #include "extensions/common/features/feature.h" 34 #include "extensions/common/features/feature.h"
34 #include "extensions/common/features/feature_provider.h" 35 #include "extensions/common/features/feature_provider.h"
35 #include "extensions/common/manifest_handlers/background_info.h" 36 #include "extensions/common/manifest_handlers/background_info.h"
36 #include "extensions/common/manifest_handlers/incognito_info.h" 37 #include "extensions/common/manifest_handlers/incognito_info.h"
37 #include "extensions/common/permissions/permissions_data.h" 38 #include "extensions/common/permissions/permissions_data.h"
38 39
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 return EventRouterFactory::GetForBrowserContext(browser_context); 141 return EventRouterFactory::GetForBrowserContext(browser_context);
141 } 142 }
142 143
143 // static 144 // static
144 std::string EventRouter::GetBaseEventName(const std::string& full_event_name) { 145 std::string EventRouter::GetBaseEventName(const std::string& full_event_name) {
145 size_t slash_sep = full_event_name.find('/'); 146 size_t slash_sep = full_event_name.find('/');
146 return full_event_name.substr(0, slash_sep); 147 return full_event_name.substr(0, slash_sep);
147 } 148 }
148 149
149 // static 150 // static
150 void EventRouter::DispatchEvent(IPC::Sender* ipc_sender, 151 void EventRouter::DispatchEventToSender(IPC::Sender* ipc_sender,
151 void* browser_context_id, 152 void* browser_context_id,
152 const std::string& extension_id, 153 const GURL& url,
153 const std::string& event_name, 154 const std::string& extension_id,
154 scoped_ptr<ListValue> event_args, 155 events::HistogramValue histogram_value,
155 UserGestureState user_gesture, 156 const std::string& event_name,
156 const EventFilteringInfo& info) { 157 scoped_ptr<ListValue> event_args,
158 UserGestureState user_gesture,
159 const EventFilteringInfo& info) {
157 int event_id = g_extension_event_id.GetNext(); 160 int event_id = g_extension_event_id.GetNext();
158 161
159 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 162 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
163 DoDispatchEventToSenderBookkeepingOnUI(browser_context_id, extension_id,
164 url, event_id, histogram_value,
165 event_name);
166 } else {
160 // This is called from WebRequest API. 167 // This is called from WebRequest API.
161 // TODO(lazyboy): Skip this entirely: http://crbug.com/488747. 168 // TODO(lazyboy): Skip this entirely: http://crbug.com/488747.
162 BrowserThread::PostTask( 169 BrowserThread::PostTask(
163 BrowserThread::UI, FROM_HERE, 170 BrowserThread::UI, FROM_HERE,
164 base::Bind(&EventRouter::IncrementInFlightEventsOnUI, 171 base::Bind(&EventRouter::DoDispatchEventToSenderBookkeepingOnUI,
165 browser_context_id, extension_id, event_id, event_name)); 172 browser_context_id, extension_id, url, event_id,
166 } else { 173 histogram_value, event_name));
167 IncrementInFlightEventsOnUI(browser_context_id, extension_id, event_id,
168 event_name);
169 } 174 }
170 175
171 DispatchExtensionMessage(ipc_sender, browser_context_id, extension_id, 176 DispatchExtensionMessage(ipc_sender, browser_context_id, extension_id,
172 event_id, event_name, event_args.get(), user_gesture, 177 event_id, event_name, event_args.get(), user_gesture,
173 info); 178 info);
174 } 179 }
175 180
176 EventRouter::EventRouter(BrowserContext* browser_context, 181 EventRouter::EventRouter(BrowserContext* browser_context,
177 ExtensionPrefs* extension_prefs) 182 ExtensionPrefs* extension_prefs)
178 : browser_context_(browser_context), 183 : browser_context_(browser_context),
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 it != listeners.end(); it++) { 521 it != listeners.end(); it++) {
517 const EventListener* listener = *it; 522 const EventListener* listener = *it;
518 if (restrict_to_extension_id.empty() || 523 if (restrict_to_extension_id.empty() ||
519 restrict_to_extension_id == listener->extension_id()) { 524 restrict_to_extension_id == listener->extension_id()) {
520 if (listener->process()) { 525 if (listener->process()) {
521 EventDispatchIdentifier dispatch_id(listener->GetBrowserContext(), 526 EventDispatchIdentifier dispatch_id(listener->GetBrowserContext(),
522 listener->extension_id()); 527 listener->extension_id());
523 if (!ContainsKey(already_dispatched, dispatch_id)) { 528 if (!ContainsKey(already_dispatched, dispatch_id)) {
524 DispatchEventToProcess(listener->extension_id(), 529 DispatchEventToProcess(listener->extension_id(),
525 listener->listener_url(), listener->process(), 530 listener->listener_url(), listener->process(),
526 event, listener->filter()); 531 event, listener->filter(), false);
Devlin 2015/08/05 21:34:09 there are a few more of the anonymous bools than I
not at google - send to devlin 2015/08/07 20:55:03 Sure.
527 } 532 }
528 } 533 }
529 } 534 }
530 } 535 }
531 } 536 }
532 537
533 void EventRouter::DispatchLazyEvent( 538 void EventRouter::DispatchLazyEvent(
534 const std::string& extension_id, 539 const std::string& extension_id,
535 const linked_ptr<Event>& event, 540 const linked_ptr<Event>& event,
536 std::set<EventDispatchIdentifier>* already_dispatched, 541 std::set<EventDispatchIdentifier>* already_dispatched,
(...skipping 23 matching lines...) Expand all
560 std::make_pair(incognito_context, extension_id)); 565 std::make_pair(incognito_context, extension_id));
561 } 566 }
562 } 567 }
563 } 568 }
564 569
565 void EventRouter::DispatchEventToProcess( 570 void EventRouter::DispatchEventToProcess(
566 const std::string& extension_id, 571 const std::string& extension_id,
567 const GURL& listener_url, 572 const GURL& listener_url,
568 content::RenderProcessHost* process, 573 content::RenderProcessHost* process,
569 const linked_ptr<Event>& event, 574 const linked_ptr<Event>& event,
570 const base::DictionaryValue* listener_filter) { 575 const base::DictionaryValue* listener_filter,
576 bool did_enqueue) {
571 BrowserContext* listener_context = process->GetBrowserContext(); 577 BrowserContext* listener_context = process->GetBrowserContext();
572 ProcessMap* process_map = ProcessMap::Get(listener_context); 578 ProcessMap* process_map = ProcessMap::Get(listener_context);
573 579
574 // NOTE: |extension| being NULL does not necessarily imply that this event 580 // NOTE: |extension| being NULL does not necessarily imply that this event
575 // shouldn't be dispatched. Events can be dispatched to WebUI and webviews as 581 // shouldn't be dispatched. Events can be dispatched to WebUI and webviews as
576 // well. It all depends on what GetMostLikelyContextType returns. 582 // well. It all depends on what GetMostLikelyContextType returns.
577 const Extension* extension = 583 const Extension* extension =
578 ExtensionRegistry::Get(browser_context_)->enabled_extensions().GetByID( 584 ExtensionRegistry::Get(browser_context_)->enabled_extensions().GetByID(
579 extension_id); 585 extension_id);
580 586
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 !event->will_dispatch_callback.Run(listener_context, extension, 634 !event->will_dispatch_callback.Run(listener_context, extension,
629 event->event_args.get(), 635 event->event_args.get(),
630 listener_filter)) { 636 listener_filter)) {
631 return; 637 return;
632 } 638 }
633 639
634 int event_id = g_extension_event_id.GetNext(); 640 int event_id = g_extension_event_id.GetNext();
635 DispatchExtensionMessage(process, listener_context, extension_id, event_id, 641 DispatchExtensionMessage(process, listener_context, extension_id, event_id,
636 event->event_name, event->event_args.get(), 642 event->event_name, event->event_args.get(),
637 event->user_gesture, event->filter_info); 643 event->user_gesture, event->filter_info);
644 ReportEvent(event->histogram_value, listener_url, did_enqueue);
638 645
639 if (extension) { 646 if (extension) {
640 IncrementInFlightEvents(listener_context, extension, event_id, 647 IncrementInFlightEvents(listener_context, extension, event_id,
641 event->event_name); 648 event->event_name);
642 } 649 }
643 } 650 }
644 651
645 bool EventRouter::CanDispatchEventToBrowserContext( 652 bool EventRouter::CanDispatchEventToBrowserContext(
646 BrowserContext* context, 653 BrowserContext* context,
647 const Extension* extension, 654 const Extension* extension,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 queue->AddPendingTask(context, extension->id(), 693 queue->AddPendingTask(context, extension->id(),
687 base::Bind(&EventRouter::DispatchPendingEvent, 694 base::Bind(&EventRouter::DispatchPendingEvent,
688 base::Unretained(this), dispatched_event)); 695 base::Unretained(this), dispatched_event));
689 return true; 696 return true;
690 } 697 }
691 698
692 return false; 699 return false;
693 } 700 }
694 701
695 // static 702 // static
696 void EventRouter::IncrementInFlightEventsOnUI(void* browser_context_id, 703 void EventRouter::DoDispatchEventToSenderBookkeepingOnUI(
697 const std::string& extension_id, 704 void* browser_context_id,
698 int event_id, 705 const std::string& extension_id,
699 const std::string& event_name) { 706 const GURL& url,
707 int event_id,
708 events::HistogramValue histogram_value,
709 const std::string& event_name) {
700 DCHECK_CURRENTLY_ON(BrowserThread::UI); 710 DCHECK_CURRENTLY_ON(BrowserThread::UI);
701 BrowserContext* browser_context = 711 BrowserContext* browser_context =
702 reinterpret_cast<BrowserContext*>(browser_context_id); 712 reinterpret_cast<BrowserContext*>(browser_context_id);
703 if (!ExtensionsBrowserClient::Get()->IsValidContext(browser_context)) 713 if (!ExtensionsBrowserClient::Get()->IsValidContext(browser_context))
704 return; 714 return;
705 EventRouter* event_router = EventRouter::Get(browser_context);
706 if (!event_router)
707 return;
708 const Extension* extension = 715 const Extension* extension =
709 ExtensionRegistry::Get(browser_context)->enabled_extensions().GetByID( 716 ExtensionRegistry::Get(browser_context)->enabled_extensions().GetByID(
710 extension_id); 717 extension_id);
711 if (!extension) 718 if (!extension)
712 return; 719 return;
720 EventRouter* event_router = EventRouter::Get(browser_context);
713 event_router->IncrementInFlightEvents(browser_context, extension, event_id, 721 event_router->IncrementInFlightEvents(browser_context, extension, event_id,
714 event_name); 722 event_name);
723 event_router->ReportEvent(histogram_value, url, false);
715 } 724 }
716 725
717 void EventRouter::IncrementInFlightEvents(BrowserContext* context, 726 void EventRouter::IncrementInFlightEvents(BrowserContext* context,
718 const Extension* extension, 727 const Extension* extension,
719 int event_id, 728 int event_id,
720 const std::string& event_name) { 729 const std::string& event_name) {
721 // TODO(chirantan): Turn this on once crbug.com/464513 is fixed. 730 // TODO(chirantan): Turn this on once crbug.com/464513 is fixed.
722 // DCHECK_CURRENTLY_ON(BrowserThread::UI); 731 // DCHECK_CURRENTLY_ON(BrowserThread::UI);
723 732
724 // Only increment in-flight events if the lazy background page is active, 733 // Only increment in-flight events if the lazy background page is active,
(...skipping 15 matching lines...) Expand all
740 // The event ACK is routed to the background host, so this should never be 749 // The event ACK is routed to the background host, so this should never be
741 // NULL. 750 // NULL.
742 CHECK(host); 751 CHECK(host);
743 // TODO(mpcomplete): We should never get this message unless 752 // TODO(mpcomplete): We should never get this message unless
744 // HasLazyBackgroundPage is true. Find out why we're getting it anyway. 753 // HasLazyBackgroundPage is true. Find out why we're getting it anyway.
745 if (host->extension() && 754 if (host->extension() &&
746 BackgroundInfo::HasLazyBackgroundPage(host->extension())) 755 BackgroundInfo::HasLazyBackgroundPage(host->extension()))
747 pm->DecrementLazyKeepaliveCount(host->extension()); 756 pm->DecrementLazyKeepaliveCount(host->extension());
748 } 757 }
749 758
759 void EventRouter::ReportEvent(events::HistogramValue histogram_value,
760 const GURL& url,
761 bool did_enqueue) {
762 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
763
764 // At this point, we're only interested in reporting events for extensions.
765 if (!url.SchemeIs(kExtensionScheme))
Devlin 2015/08/05 21:34:09 Doesn't this mean we won't log any events for mess
not at google - send to devlin 2015/08/07 20:55:03 The URL was the target URL which assuming messagin
766 return;
767
768 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
769 const Extension* extension =
770 registry->enabled_extensions().GetExtensionOrAppByURL(url);
771 if (!extension) {
772 NOTREACHED() << "Reporting event for non-existent extension at " << url;
Devlin 2015/08/05 21:34:09 Doing a NOTREACHED(); return; is typically a disco
not at google - send to devlin 2015/08/07 20:55:03 Deliberate choice - I don't trust call sites, espe
773 return;
774 }
775
776 // TODO(kalman): UMA for dispatched event.
777 // TODO(kalman): UMA specifically for component extensions.
not at google - send to devlin 2015/08/05 20:23:43 I will add the UMA_HISTOGRAM_ENUMERATION calls in
778
779 switch (GetExtensionPageType(extension, url, did_enqueue)) {
780 case EXTENSION_PAGE_NONE:
781 break;
782 case EXTENSION_PAGE_VIEW:
783 // TODO(kalman): UMA for dispatched event to view.
784 break;
785 case EXTENSION_PAGE_PERSISTENT_BACKGROUND:
786 // TODO(kalman): UMA for dispatched event to persistent background page.
787 break;
788 case EXTENSION_PAGE_DORMANT_EVENT:
789 // TODO(kalman): UMA for dispatched event that woke up event page.
790 break;
791 case EXTENSION_PAGE_AWAKE_EVENT:
792 // TODO(kalman): UMA for dispatched event to awake up event page.
793 break;
794 }
795 }
796
797 EventRouter::ExtensionPageType EventRouter::GetExtensionPageType(
798 const Extension* extension,
799 const GURL& url,
800 bool did_enqueue) {
801 if (!extension)
Devlin 2015/08/05 21:34:09 When could this happen?
not at google - send to devlin 2015/08/07 20:55:03 In a previous version of the patch, I guess - and
802 return EXTENSION_PAGE_NONE;
803 if (url == BackgroundInfo::GetBackgroundURL(extension)) {
804 if (BackgroundInfo::HasPersistentBackgroundPage(extension))
805 return EXTENSION_PAGE_PERSISTENT_BACKGROUND;
806 if (BackgroundInfo::HasLazyBackgroundPage(extension))
807 return did_enqueue ? EXTENSION_PAGE_DORMANT_EVENT
808 : EXTENSION_PAGE_AWAKE_EVENT;
809 }
810 return EXTENSION_PAGE_VIEW;
811 }
812
750 void EventRouter::DispatchPendingEvent(const linked_ptr<Event>& event, 813 void EventRouter::DispatchPendingEvent(const linked_ptr<Event>& event,
751 ExtensionHost* host) { 814 ExtensionHost* host) {
752 if (!host) 815 if (!host)
753 return; 816 return;
754 817
755 if (listeners_.HasProcessListener(host->render_process_host(), 818 if (listeners_.HasProcessListener(host->render_process_host(),
756 host->extension()->id())) { 819 host->extension()->id())) {
757 // URL events cannot be lazy therefore can't be pending, hence the GURL(). 820 // URL events cannot be lazy therefore can't be pending, hence the GURL().
758 DispatchEventToProcess(host->extension()->id(), GURL(), 821 DispatchEventToProcess(host->extension()->id(), GURL(),
759 host->render_process_host(), event, nullptr); 822 host->render_process_host(), event, nullptr, true);
760 } 823 }
761 } 824 }
762 825
763 void EventRouter::Observe(int type, 826 void EventRouter::Observe(int type,
764 const content::NotificationSource& source, 827 const content::NotificationSource& source,
765 const content::NotificationDetails& details) { 828 const content::NotificationDetails& details) {
766 switch (type) { 829 switch (type) {
767 case extensions::NOTIFICATION_EXTENSION_ENABLED: { 830 case extensions::NOTIFICATION_EXTENSION_ENABLED: {
768 // If the extension has a lazy background page, make sure it gets loaded 831 // If the extension has a lazy background page, make sure it gets loaded
769 // to register the events the extension is interested in. 832 // to register the events the extension is interested in.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 const std::string& extension_id, 918 const std::string& extension_id,
856 const GURL& listener_url, 919 const GURL& listener_url,
857 content::BrowserContext* browser_context) 920 content::BrowserContext* browser_context)
858 : event_name(event_name), 921 : event_name(event_name),
859 extension_id(extension_id), 922 extension_id(extension_id),
860 listener_url(listener_url), 923 listener_url(listener_url),
861 browser_context(browser_context) { 924 browser_context(browser_context) {
862 } 925 }
863 926
864 } // namespace extensions 927 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698