OLD | NEW |
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/json_writer.h" | 7 #include "base/json_writer.h" |
8 #include "base/singleton.h" | 8 #include "base/singleton.h" |
9 #include "base/stl_util-inl.h" | 9 #include "base/stl_util-inl.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 const char ExtensionMessageService::kDispatchOnConnect[] = | 98 const char ExtensionMessageService::kDispatchOnConnect[] = |
99 "Port.dispatchOnConnect"; | 99 "Port.dispatchOnConnect"; |
100 const char ExtensionMessageService::kDispatchOnDisconnect[] = | 100 const char ExtensionMessageService::kDispatchOnDisconnect[] = |
101 "Port.dispatchOnDisconnect"; | 101 "Port.dispatchOnDisconnect"; |
102 const char ExtensionMessageService::kDispatchOnMessage[] = | 102 const char ExtensionMessageService::kDispatchOnMessage[] = |
103 "Port.dispatchOnMessage"; | 103 "Port.dispatchOnMessage"; |
104 const char ExtensionMessageService::kDispatchEvent[] = | 104 const char ExtensionMessageService::kDispatchEvent[] = |
105 "Event.dispatchJSON"; | 105 "Event.dispatchJSON"; |
106 | 106 |
107 ExtensionMessageService::ExtensionMessageService(Profile* profile) | 107 ExtensionMessageService::ExtensionMessageService(Profile* profile) |
108 : ui_loop_(MessageLoop::current()), profile_(profile), next_port_id_(0) { | 108 : ui_loop_(MessageLoop::current()), |
| 109 profile_(profile), |
| 110 extension_devtools_manager_(NULL), |
| 111 next_port_id_(0) { |
109 DCHECK_EQ(ui_loop_->type(), MessageLoop::TYPE_UI); | 112 DCHECK_EQ(ui_loop_->type(), MessageLoop::TYPE_UI); |
110 | 113 |
111 registrar_.Add(this, NotificationType::RENDERER_PROCESS_TERMINATED, | 114 registrar_.Add(this, NotificationType::RENDERER_PROCESS_TERMINATED, |
112 NotificationService::AllSources()); | 115 NotificationService::AllSources()); |
113 registrar_.Add(this, NotificationType::RENDERER_PROCESS_CLOSED, | 116 registrar_.Add(this, NotificationType::RENDERER_PROCESS_CLOSED, |
114 NotificationService::AllSources()); | 117 NotificationService::AllSources()); |
115 registrar_.Add(this, NotificationType::RENDER_VIEW_HOST_DELETED, | 118 registrar_.Add(this, NotificationType::RENDER_VIEW_HOST_DELETED, |
116 NotificationService::AllSources()); | 119 NotificationService::AllSources()); |
| 120 |
| 121 extension_devtools_manager_ = profile_->GetExtensionDevToolsManager(); |
117 } | 122 } |
118 | 123 |
119 ExtensionMessageService::~ExtensionMessageService() { | 124 ExtensionMessageService::~ExtensionMessageService() { |
120 } | 125 } |
121 | 126 |
122 void ExtensionMessageService::ProfileDestroyed() { | 127 void ExtensionMessageService::ProfileDestroyed() { |
123 DCHECK_EQ(ui_loop_->type(), MessageLoop::TYPE_UI); | 128 DCHECK_EQ(ui_loop_->type(), MessageLoop::TYPE_UI); |
124 | 129 |
125 profile_ = NULL; | 130 profile_ = NULL; |
126 | 131 |
127 // We remove notifications here because our destructor might be called on | 132 // We remove notifications here because our destructor might be called on |
128 // a non-UI thread. | 133 // a non-UI thread. |
129 registrar_.RemoveAll(); | 134 registrar_.RemoveAll(); |
130 } | 135 } |
131 | 136 |
132 void ExtensionMessageService::AddEventListener(const std::string& event_name, | 137 void ExtensionMessageService::AddEventListener(const std::string& event_name, |
133 int render_process_id) { | 138 int render_process_id) { |
134 DCHECK(RenderProcessHost::FromID(render_process_id)) << | 139 DCHECK(RenderProcessHost::FromID(render_process_id)) << |
135 "Adding event listener to a non-existant RenderProcessHost."; | 140 "Adding event listener to a non-existant RenderProcessHost."; |
136 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 141 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
137 DCHECK_EQ(listeners_[event_name].count(render_process_id), 0u) << event_name; | 142 DCHECK_EQ(listeners_[event_name].count(render_process_id), 0u) << event_name; |
138 listeners_[event_name].insert(render_process_id); | 143 listeners_[event_name].insert(render_process_id); |
| 144 |
| 145 if (extension_devtools_manager_.get()) { |
| 146 extension_devtools_manager_->AddEventListener(event_name, |
| 147 render_process_id); |
| 148 } |
139 } | 149 } |
140 | 150 |
141 void ExtensionMessageService::RemoveEventListener(const std::string& event_name, | 151 void ExtensionMessageService::RemoveEventListener(const std::string& event_name, |
142 int render_process_id) { | 152 int render_process_id) { |
143 // It is possible that this RenderProcessHost is being destroyed. If that is | 153 // It is possible that this RenderProcessHost is being destroyed. If that is |
144 // the case, we'll have already removed his listeners, so do nothing here. | 154 // the case, we'll have already removed his listeners, so do nothing here. |
145 RenderProcessHost* rph = RenderProcessHost::FromID(render_process_id); | 155 RenderProcessHost* rph = RenderProcessHost::FromID(render_process_id); |
146 if (!rph) | 156 if (!rph) |
147 return; | 157 return; |
148 | 158 |
149 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 159 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
150 DCHECK_EQ(listeners_[event_name].count(render_process_id), 1u) << event_name; | 160 DCHECK_EQ(listeners_[event_name].count(render_process_id), 1u) << event_name; |
151 listeners_[event_name].erase(render_process_id); | 161 listeners_[event_name].erase(render_process_id); |
| 162 |
| 163 if (extension_devtools_manager_.get()) { |
| 164 extension_devtools_manager_->RemoveEventListener(event_name, |
| 165 render_process_id); |
| 166 } |
152 } | 167 } |
153 | 168 |
154 void ExtensionMessageService::AllocatePortIdPair(int* port1, int* port2) { | 169 void ExtensionMessageService::AllocatePortIdPair(int* port1, int* port2) { |
155 AutoLock lock(next_port_id_lock_); | 170 AutoLock lock(next_port_id_lock_); |
156 | 171 |
157 // TODO(mpcomplete): what happens when this wraps? | 172 // TODO(mpcomplete): what happens when this wraps? |
158 int port1_id = next_port_id_++; | 173 int port1_id = next_port_id_++; |
159 int port2_id = next_port_id_++; | 174 int port2_id = next_port_id_++; |
160 | 175 |
161 DCHECK(IS_OPENER_PORT_ID(port1_id)); | 176 DCHECK(IS_OPENER_PORT_ID(port1_id)); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 353 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
339 | 354 |
340 // Notify the other side. | 355 // Notify the other side. |
341 const MessagePort& port = IS_OPENER_PORT_ID(closing_port_id) ? | 356 const MessagePort& port = IS_OPENER_PORT_ID(closing_port_id) ? |
342 channel_iter->second->receiver : channel_iter->second->opener; | 357 channel_iter->second->receiver : channel_iter->second->opener; |
343 | 358 |
344 DispatchOnDisconnect(port, GET_OPPOSITE_PORT_ID(closing_port_id)); | 359 DispatchOnDisconnect(port, GET_OPPOSITE_PORT_ID(closing_port_id)); |
345 channels_.erase(channel_iter); | 360 channels_.erase(channel_iter); |
346 } | 361 } |
347 | 362 |
| 363 |
348 void ExtensionMessageService::PostMessageFromRenderer( | 364 void ExtensionMessageService::PostMessageFromRenderer( |
349 int source_port_id, const std::string& message) { | 365 int source_port_id, const std::string& message) { |
350 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 366 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
351 | 367 |
352 MessageChannelMap::iterator iter = | 368 MessageChannelMap::iterator iter = |
353 channels_.find(GET_CHANNEL_ID(source_port_id)); | 369 channels_.find(GET_CHANNEL_ID(source_port_id)); |
354 if (iter == channels_.end()) | 370 if (iter == channels_.end()) |
355 return; | 371 return; |
356 | 372 |
357 // Figure out which port the ID corresponds to. | 373 // Figure out which port the ID corresponds to. |
(...skipping 29 matching lines...) Expand all Loading... |
387 const NotificationSource& source, | 403 const NotificationSource& source, |
388 const NotificationDetails& details) { | 404 const NotificationDetails& details) { |
389 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 405 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
390 | 406 |
391 switch (type.value) { | 407 switch (type.value) { |
392 case NotificationType::RENDERER_PROCESS_TERMINATED: | 408 case NotificationType::RENDERER_PROCESS_TERMINATED: |
393 case NotificationType::RENDERER_PROCESS_CLOSED: { | 409 case NotificationType::RENDERER_PROCESS_CLOSED: { |
394 RenderProcessHost* renderer = Source<RenderProcessHost>(source).ptr(); | 410 RenderProcessHost* renderer = Source<RenderProcessHost>(source).ptr(); |
395 OnSenderClosed(renderer); | 411 OnSenderClosed(renderer); |
396 | 412 |
397 // Remove this renderer from our listener maps. | 413 // Remove all event listeners associated with this renderer |
398 for (ListenerMap::iterator it = listeners_.begin(); | 414 for (ListenerMap::iterator it = listeners_.begin(); |
399 it != listeners_.end(); ) { | 415 it != listeners_.end(); ) { |
400 ListenerMap::iterator current = it++; | 416 ListenerMap::iterator current = it++; |
401 current->second.erase(renderer->pid()); | 417 if (current->second.count(renderer->pid()) != 0) |
402 if (current->second.empty()) | 418 RemoveEventListener(current->first, renderer->pid()); |
403 listeners_.erase(current); | |
404 } | 419 } |
405 break; | 420 break; |
406 } | 421 } |
407 case NotificationType::RENDER_VIEW_HOST_DELETED: | 422 case NotificationType::RENDER_VIEW_HOST_DELETED: |
408 OnSenderClosed(Details<RenderViewHost>(details).ptr()); | 423 OnSenderClosed(Details<RenderViewHost>(details).ptr()); |
409 break; | 424 break; |
410 default: | 425 default: |
411 NOTREACHED(); | 426 NOTREACHED(); |
412 return; | 427 return; |
413 } | 428 } |
414 } | 429 } |
415 | 430 |
416 void ExtensionMessageService::OnSenderClosed(IPC::Message::Sender* sender) { | 431 void ExtensionMessageService::OnSenderClosed(IPC::Message::Sender* sender) { |
417 // Close any channels that share this renderer. We notify the opposite | 432 // Close any channels that share this renderer. We notify the opposite |
418 // port that his pair has closed. | 433 // port that his pair has closed. |
419 for (MessageChannelMap::iterator it = channels_.begin(); | 434 for (MessageChannelMap::iterator it = channels_.begin(); |
420 it != channels_.end(); ) { | 435 it != channels_.end(); ) { |
421 MessageChannelMap::iterator current = it++; | 436 MessageChannelMap::iterator current = it++; |
422 if (current->second->opener.sender == sender) { | 437 if (current->second->opener.sender == sender) { |
423 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first)); | 438 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first)); |
424 } else if (current->second->receiver.sender == sender) { | 439 } else if (current->second->receiver.sender == sender) { |
425 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first)); | 440 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first)); |
426 } | 441 } |
427 } | 442 } |
428 } | 443 } |
OLD | NEW |