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

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

Issue 11946028: Record event activity to the extension activity log. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fix for ExtensionService being unavailable during unit tests Created 7 years, 11 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 "chrome/browser/extensions/event_router.h" 5 #include "chrome/browser/extensions/event_router.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/stl_util.h" 12 #include "base/stl_util.h"
13 #include "base/values.h" 13 #include "base/values.h"
14 #include "base/version.h" 14 #include "base/version.h"
15 #include "chrome/browser/browser_process.h" 15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/extensions/activity_log.h"
16 #include "chrome/browser/extensions/api/runtime/runtime_api.h" 17 #include "chrome/browser/extensions/api/runtime/runtime_api.h"
17 #include "chrome/browser/extensions/api/web_request/web_request_api.h" 18 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
18 #include "chrome/browser/extensions/event_names.h" 19 #include "chrome/browser/extensions/event_names.h"
19 #include "chrome/browser/extensions/extension_host.h" 20 #include "chrome/browser/extensions/extension_host.h"
20 #include "chrome/browser/extensions/extension_prefs.h" 21 #include "chrome/browser/extensions/extension_prefs.h"
21 #include "chrome/browser/extensions/extension_process_manager.h" 22 #include "chrome/browser/extensions/extension_process_manager.h"
22 #include "chrome/browser/extensions/extension_service.h" 23 #include "chrome/browser/extensions/extension_service.h"
23 #include "chrome/browser/extensions/extension_system.h" 24 #include "chrome/browser/extensions/extension_system.h"
24 #include "chrome/browser/extensions/lazy_background_task_queue.h" 25 #include "chrome/browser/extensions/lazy_background_task_queue.h"
25 #include "chrome/browser/extensions/process_map.h" 26 #include "chrome/browser/extensions/process_map.h"
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 bool operator<(const ListenerProcess& that) const { 80 bool operator<(const ListenerProcess& that) const {
80 if (process < that.process) 81 if (process < that.process)
81 return true; 82 return true;
82 if (process == that.process && extension_id < that.extension_id) 83 if (process == that.process && extension_id < that.extension_id)
83 return true; 84 return true;
84 return false; 85 return false;
85 } 86 }
86 }; 87 };
87 88
88 // static 89 // static
90 void EventRouter::LogExtensionEventMessage(Profile* profile,
91 const std::string& extension_id,
92 const std::string& event_name,
93 scoped_ptr<ListValue> event_args) {
94 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
95 BrowserThread::PostTask(BrowserThread::UI,
96 FROM_HERE,
97 base::Bind(&LogExtensionEventMessage,
98 profile,
99 extension_id,
100 event_name,
101 Passed(event_args.Pass())));
102 } else {
103 // An ExtensionService might not be running during unit tests, or an
104 // extension might have been unloaded by the time we get to logging it. In
105 // those cases log a warning.
106 ExtensionService* extension_service =
107 ExtensionSystem::Get(profile)->extension_service();
108 if (!extension_service) {
109 LOG(WARNING) << "ExtensionService does not seem to be available "
110 << "(this may be normal for unit tests)";
111 } else {
112 const Extension* extension =
113 extension_service->extensions()->GetByID(extension_id);
114 if (!extension) {
115 LOG(WARNING) << "Extension " << extension_id << " not found!";
116 } else {
117 extensions::ActivityLog::GetInstance(profile)->LogEventAction(
118 extension, event_name, event_args.get(), "");
119 }
120 }
121 }
122 }
123
124 // static
89 void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender, 125 void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender,
126 Profile* profile,
90 const std::string& extension_id, 127 const std::string& extension_id,
91 const std::string& event_name, 128 const std::string& event_name,
92 ListValue* event_args, 129 ListValue* event_args,
93 const GURL& event_url, 130 const GURL& event_url,
94 UserGestureState user_gesture, 131 UserGestureState user_gesture,
95 const EventFilteringInfo& info) { 132 const EventFilteringInfo& info) {
133 LogExtensionEventMessage(profile, extension_id, event_name,
134 scoped_ptr<ListValue>(event_args->DeepCopy()));
Matt Perry 2013/01/25 21:24:17 Can we only do this copying if activity logging is
mvrable 2013/01/28 16:27:36 Done, if the updated code looks good to you.
135
96 ListValue args; 136 ListValue args;
97 args.Set(0, Value::CreateStringValue(event_name)); 137 args.Set(0, Value::CreateStringValue(event_name));
98 args.Set(1, event_args); 138 args.Set(1, event_args);
99 args.Set(2, info.AsValue().release()); 139 args.Set(2, info.AsValue().release());
100 ipc_sender->Send(new ExtensionMsg_MessageInvoke(MSG_ROUTING_CONTROL, 140 ipc_sender->Send(new ExtensionMsg_MessageInvoke(MSG_ROUTING_CONTROL,
101 extension_id, kDispatchEvent, args, event_url, 141 extension_id, kDispatchEvent, args, event_url,
102 user_gesture == USER_GESTURE_ENABLED)); 142 user_gesture == USER_GESTURE_ENABLED));
103 143
104 // DispatchExtensionMessage does _not_ take ownership of event_args, so we 144 // DispatchExtensionMessage does _not_ take ownership of event_args, so we
105 // must ensure that the destruction of args does not attempt to free it. 145 // must ensure that the destruction of args does not attempt to free it.
106 Value* removed_event_args = NULL; 146 Value* removed_event_args = NULL;
107 args.Remove(1, &removed_event_args); 147 args.Remove(1, &removed_event_args);
108 } 148 }
109 149
110 // static 150 // static
111 void EventRouter::DispatchEvent(IPC::Sender* ipc_sender, 151 void EventRouter::DispatchEvent(IPC::Sender* ipc_sender,
152 Profile* profile,
112 const std::string& extension_id, 153 const std::string& extension_id,
113 const std::string& event_name, 154 const std::string& event_name,
114 scoped_ptr<ListValue> event_args, 155 scoped_ptr<ListValue> event_args,
115 const GURL& event_url, 156 const GURL& event_url,
116 UserGestureState user_gesture, 157 UserGestureState user_gesture,
117 const EventFilteringInfo& info) { 158 const EventFilteringInfo& info) {
118 DispatchExtensionMessage(ipc_sender, extension_id, event_name, 159 DispatchExtensionMessage(ipc_sender, profile, extension_id, event_name,
119 event_args.get(), event_url, user_gesture, info); 160 event_args.get(), event_url, user_gesture, info);
120 } 161 }
121 162
122 EventRouter::EventRouter(Profile* profile, ExtensionPrefs* extension_prefs) 163 EventRouter::EventRouter(Profile* profile, ExtensionPrefs* extension_prefs)
123 : profile_(profile), 164 : profile_(profile),
124 listeners_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 165 listeners_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
166 activity_log_(ActivityLog::GetInstance(profile)),
125 dispatch_chrome_updated_event_(false) { 167 dispatch_chrome_updated_event_(false) {
126 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 168 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
127 content::NotificationService::AllSources()); 169 content::NotificationService::AllSources());
128 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, 170 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
129 content::NotificationService::AllSources()); 171 content::NotificationService::AllSources());
130 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, 172 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
131 content::Source<Profile>(profile_)); 173 content::Source<Profile>(profile_));
132 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_ENABLED, 174 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_ENABLED,
133 content::Source<Profile>(profile_)); 175 content::Source<Profile>(profile_));
134 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, 176 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 225
184 void EventRouter::OnListenerAdded(const EventListener* listener) { 226 void EventRouter::OnListenerAdded(const EventListener* listener) {
185 const std::string& event_name = listener->event_name; 227 const std::string& event_name = listener->event_name;
186 const EventListenerInfo details(event_name, listener->extension_id); 228 const EventListenerInfo details(event_name, listener->extension_id);
187 ObserverMap::iterator observer = observers_.find(event_name); 229 ObserverMap::iterator observer = observers_.find(event_name);
188 if (observer != observers_.end()) 230 if (observer != observers_.end())
189 observer->second->OnListenerAdded(details); 231 observer->second->OnListenerAdded(details);
190 232
191 if (SystemInfoEventRouter::IsSystemInfoEvent(event_name)) 233 if (SystemInfoEventRouter::IsSystemInfoEvent(event_name))
192 SystemInfoEventRouter::GetInstance()->AddEventListener(event_name); 234 SystemInfoEventRouter::GetInstance()->AddEventListener(event_name);
235
236 const Extension* extension = extensions::ExtensionSystem::Get(profile_)->
237 extension_service()->GetExtensionById(listener->extension_id,
238 ExtensionService::INCLUDE_ENABLED);
239 if (extension) {
240 scoped_ptr<ListValue> args(new ListValue());
241 if (listener->filter)
242 args->Append(listener->filter->DeepCopy());
243 activity_log_->LogAPIAction(extension,
244 event_name + ".addListener",
245 args.get(),
246 "");
247 }
193 } 248 }
194 249
195 void EventRouter::OnListenerRemoved(const EventListener* listener) { 250 void EventRouter::OnListenerRemoved(const EventListener* listener) {
196 const std::string& event_name = listener->event_name; 251 const std::string& event_name = listener->event_name;
197 const EventListenerInfo details(event_name, listener->extension_id); 252 const EventListenerInfo details(event_name, listener->extension_id);
198 ObserverMap::iterator observer = observers_.find(event_name); 253 ObserverMap::iterator observer = observers_.find(event_name);
199 if (observer != observers_.end()) 254 if (observer != observers_.end())
200 observer->second->OnListenerRemoved(details); 255 observer->second->OnListenerRemoved(details);
201 256
202 BrowserThread::PostTask( 257 BrowserThread::PostTask(
203 BrowserThread::IO, FROM_HERE, 258 BrowserThread::IO, FROM_HERE,
204 base::Bind(&NotifyEventListenerRemovedOnIOThread, 259 base::Bind(&NotifyEventListenerRemovedOnIOThread,
205 profile_, listener->extension_id, event_name)); 260 profile_, listener->extension_id, event_name));
206 261
207 if (SystemInfoEventRouter::IsSystemInfoEvent(event_name)) 262 if (SystemInfoEventRouter::IsSystemInfoEvent(event_name))
208 SystemInfoEventRouter::GetInstance()->RemoveEventListener(event_name); 263 SystemInfoEventRouter::GetInstance()->RemoveEventListener(event_name);
264
265 const Extension* extension = extensions::ExtensionSystem::Get(profile_)->
266 extension_service()->GetExtensionById(listener->extension_id,
267 ExtensionService::INCLUDE_ENABLED);
268 if (extension) {
269 scoped_ptr<ListValue> args(new ListValue());
270 activity_log_->LogAPIAction(extension,
271 event_name + ".removeListener",
272 args.get(),
273 "");
274 }
209 } 275 }
210 276
211 void EventRouter::AddLazyEventListener(const std::string& event_name, 277 void EventRouter::AddLazyEventListener(const std::string& event_name,
212 const std::string& extension_id) { 278 const std::string& extension_id) {
213 scoped_ptr<EventListener> listener(new EventListener( 279 scoped_ptr<EventListener> listener(new EventListener(
214 event_name, extension_id, NULL, scoped_ptr<DictionaryValue>())); 280 event_name, extension_id, NULL, scoped_ptr<DictionaryValue>()));
215 bool is_new = listeners_.AddListener(listener.Pass()); 281 bool is_new = listeners_.AddListener(listener.Pass());
216 282
217 if (is_new) { 283 if (is_new) {
218 ExtensionPrefs* prefs = extensions::ExtensionSystem::Get(profile_)-> 284 ExtensionPrefs* prefs = extensions::ExtensionSystem::Get(profile_)->
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 } 485 }
420 486
421 if (!CanDispatchEventToProfile(listener_profile, extension, event)) 487 if (!CanDispatchEventToProfile(listener_profile, extension, event))
422 return; 488 return;
423 489
424 if (!event->will_dispatch_callback.is_null()) { 490 if (!event->will_dispatch_callback.is_null()) {
425 event->will_dispatch_callback.Run(listener_profile, extension, 491 event->will_dispatch_callback.Run(listener_profile, extension,
426 event->event_args.get()); 492 event->event_args.get());
427 } 493 }
428 494
429 DispatchExtensionMessage(process, extension_id, 495 DispatchExtensionMessage(process, listener_profile, extension_id,
430 event->event_name, event->event_args.get(), 496 event->event_name, event->event_args.get(),
431 event->event_url, event->user_gesture, 497 event->event_url, event->user_gesture,
432 event->filter_info); 498 event->filter_info);
433 IncrementInFlightEvents(listener_profile, extension); 499 IncrementInFlightEvents(listener_profile, extension);
434 } 500 }
435 501
436 bool EventRouter::CanDispatchEventToProfile(Profile* profile, 502 bool EventRouter::CanDispatchEventToProfile(Profile* profile,
437 const Extension* extension, 503 const Extension* extension,
438 const linked_ptr<Event>& event) { 504 const linked_ptr<Event>& event) {
439 // Is this event from a different profile than the renderer (ie, an 505 // Is this event from a different profile than the renderer (ie, an
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 copy->will_dispatch_callback = will_dispatch_callback; 714 copy->will_dispatch_callback = will_dispatch_callback;
649 return copy; 715 return copy;
650 } 716 }
651 717
652 EventListenerInfo::EventListenerInfo(const std::string& event_name, 718 EventListenerInfo::EventListenerInfo(const std::string& event_name,
653 const std::string& extension_id) 719 const std::string& extension_id)
654 : event_name(event_name), 720 : event_name(event_name),
655 extension_id(extension_id) {} 721 extension_id(extension_id) {}
656 722
657 } // namespace extensions 723 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698