| 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 |