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

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

Issue 100214: Only send events to renderers that are listening to an event.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/extension_message_service.h" 5 #include "chrome/browser/extensions/extension_message_service.h"
6 6
7 #include "base/singleton.h" 7 #include "base/singleton.h"
8 #include "base/values.h" 8 #include "base/values.h"
9 #include "chrome/browser/chrome_thread.h" 9 #include "chrome/browser/chrome_thread.h"
10 #include "chrome/browser/extensions/extension.h" 10 #include "chrome/browser/extensions/extension.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 } 57 }
58 return instance; 58 return instance;
59 } 59 }
60 60
61 ExtensionMessageService::ExtensionMessageService() 61 ExtensionMessageService::ExtensionMessageService()
62 : next_port_id_(0), observing_renderer_shutdown_(false) { 62 : next_port_id_(0), observing_renderer_shutdown_(false) {
63 } 63 }
64 64
65 void ExtensionMessageService::RegisterExtension( 65 void ExtensionMessageService::RegisterExtension(
66 const std::string& extension_id, int render_process_id) { 66 const std::string& extension_id, int render_process_id) {
67 DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI);
67 AutoLock lock(process_ids_lock_); 68 AutoLock lock(process_ids_lock_);
68 DCHECK(process_ids_.find(extension_id) == process_ids_.end() || 69 DCHECK(process_ids_.find(extension_id) == process_ids_.end() ||
69 process_ids_[extension_id] == render_process_id); 70 process_ids_[extension_id] == render_process_id);
70 process_ids_[extension_id] = render_process_id; 71 process_ids_[extension_id] = render_process_id;
71 } 72 }
72 73
74 void ExtensionMessageService::AddEventListener(std::string event_name,
75 int render_process_id) {
76 DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI);
77 AutoLock lock(listener_lock_);
78 DCHECK(listeners_[event_name].count(render_process_id) == 0);
79 listeners_[event_name].insert(render_process_id);
80 }
81
82 void ExtensionMessageService::RemoveEventListener(std::string event_name,
83 int render_process_id) {
84 DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI);
85 AutoLock lock(listener_lock_);
86 DCHECK(listeners_[event_name].count(render_process_id) == 1);
87 listeners_[event_name].erase(render_process_id);
88 }
89
73 int ExtensionMessageService::OpenChannelToExtension( 90 int ExtensionMessageService::OpenChannelToExtension(
74 const std::string& extension_id, ResourceMessageFilter* source) { 91 const std::string& extension_id, ResourceMessageFilter* source) {
75 DCHECK(MessageLoop::current() == 92 DCHECK(MessageLoop::current() ==
76 ChromeThread::GetMessageLoop(ChromeThread::IO)); 93 ChromeThread::GetMessageLoop(ChromeThread::IO));
77 94
78 // Lookup the targeted extension process. 95 // Lookup the targeted extension process.
79 int process_id; 96 int process_id;
80 { 97 {
81 AutoLock lock(process_ids_lock_); 98 AutoLock lock(process_ids_lock_);
82 ProcessIDMap::iterator process_id_it = process_ids_.find( 99 ProcessIDMap::iterator process_id_it = process_ids_.find(
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 dest = channel.port2; 148 dest = channel.port2;
132 DCHECK(source == channel.port1); 149 DCHECK(source == channel.port1);
133 } 150 }
134 151
135 int source_port_id = GET_OPPOSITE_PORT_ID(port_id); 152 int source_port_id = GET_OPPOSITE_PORT_ID(port_id);
136 dest->Send(new ViewMsg_ExtensionHandleMessage(message, source_port_id)); 153 dest->Send(new ViewMsg_ExtensionHandleMessage(message, source_port_id));
137 } 154 }
138 155
139 void ExtensionMessageService::DispatchEventToRenderers( 156 void ExtensionMessageService::DispatchEventToRenderers(
140 const std::string& event_name, const std::string& event_args) { 157 const std::string& event_name, const std::string& event_args) {
158 std::set<int> pids;
159 {
160 AutoLock lock(listener_lock_);
161 pids = listeners_[event_name];
162 if (pids.empty())
163 return;
164 }
141 MessageLoop* io_thread = ChromeThread::GetMessageLoop(ChromeThread::IO); 165 MessageLoop* io_thread = ChromeThread::GetMessageLoop(ChromeThread::IO);
142 if (MessageLoop::current() != io_thread) { 166 if (MessageLoop::current() != io_thread) {
143 // Do the actual work on the IO thread. 167 // Do the actual work on the IO thread.
144 io_thread->PostTask(FROM_HERE, NewRunnableMethod(this, 168 io_thread->PostTask(FROM_HERE, NewRunnableMethod(this,
145 &ExtensionMessageService::DispatchEventToRenderers, 169 &ExtensionMessageService::DispatchEventToRenderers,
146 event_name, event_args)); 170 event_name, event_args));
147 return; 171 return;
148 } 172 }
149 173
150 // TODO(mpcomplete): we should only send messages to extension process 174 // Send the event only to renderers that are listening for it.
151 // renderers. 175 for (std::set<int>::iterator pid = pids.begin(); pid != pids.end(); ++pid) {
152 std::set<ResourceMessageFilter*>::iterator renderer; 176 RendererMap::iterator renderer = renderers_.find(*pid);
153 for (renderer = renderers_unique_.begin(); 177 if (renderer == renderers_.end())
154 renderer != renderers_unique_.end(); ++renderer) { 178 continue;
155 (*renderer)->Send(new ViewMsg_ExtensionHandleEvent(event_name, event_args)); 179 ResourceMessageFilter* filter = renderer->second;
180 filter->Send(new ViewMsg_ExtensionHandleEvent(event_name, event_args));
156 } 181 }
157 } 182 }
158 183
159 void ExtensionMessageService::RendererReady(ResourceMessageFilter* renderer) { 184 void ExtensionMessageService::RendererReady(ResourceMessageFilter* renderer) {
160 DCHECK(MessageLoop::current() == 185 DCHECK(MessageLoop::current() ==
161 ChromeThread::GetMessageLoop(ChromeThread::IO)); 186 ChromeThread::GetMessageLoop(ChromeThread::IO));
162 187
163 DCHECK(renderers_.find(renderer->GetProcessId()) == renderers_.end()); 188 DCHECK(renderers_.find(renderer->GetProcessId()) == renderers_.end());
164 renderers_[renderer->GetProcessId()] = renderer; 189 renderers_[renderer->GetProcessId()] = renderer;
165 renderers_unique_.insert(renderer); 190 renderers_unique_.insert(renderer);
166 191
167 if (!observing_renderer_shutdown_) { 192 if (!observing_renderer_shutdown_) {
168 observing_renderer_shutdown_ = true; 193 observing_renderer_shutdown_ = true;
169 NotificationService::current()->AddObserver( 194 NotificationService::current()->AddObserver(
170 this, 195 this,
171 NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN, 196 NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN,
172 NotificationService::AllSources()); 197 NotificationService::AllSources());
173 } 198 }
174 } 199 }
175 200
176 void ExtensionMessageService::Observe(NotificationType type, 201 void ExtensionMessageService::Observe(NotificationType type,
177 const NotificationSource& source, 202 const NotificationSource& source,
178 const NotificationDetails& details) { 203 const NotificationDetails& details) {
179 DCHECK(MessageLoop::current() == 204 DCHECK(MessageLoop::current() ==
180 ChromeThread::GetMessageLoop(ChromeThread::IO)); 205 ChromeThread::GetMessageLoop(ChromeThread::IO));
181 206
182 DCHECK(type.value == NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN); 207 DCHECK(type.value == NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN);
183 ResourceMessageFilter* renderer = Source<ResourceMessageFilter>(source).ptr(); 208 ResourceMessageFilter* renderer = Source<ResourceMessageFilter>(source).ptr();
184 209
185 renderers_.erase(renderer->GetProcessId()); 210 renderers_.erase(renderer->GetProcessId());
186 renderers_unique_.erase(renderer); 211 renderers_unique_.erase(renderer);
187 212
188 // Close any channels that share this renderer. 213 // Close any channels that share this renderer.
189 // TODO(mpcomplete): should we notify the other side of the port? 214 // TODO(mpcomplete): should we notify the other side of the port?
190 for (MessageChannelMap::iterator it = channels_.begin(); 215 for (MessageChannelMap::iterator it = channels_.begin();
191 it != channels_.end(); ) { 216 it != channels_.end(); ) {
192 MessageChannelMap::iterator current = it++; 217 MessageChannelMap::iterator current = it++;
193 if (current->second.port1 == renderer || current->second.port2 == renderer) 218 if (current->second.port1 == renderer || current->second.port2 == renderer)
194 channels_.erase(current); 219 channels_.erase(current);
195 } 220 }
196 } 221 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_message_service.h ('k') | chrome/browser/extensions/extension_messages_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698