Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/extension_message_service.h" | 5 #include "chrome/browser/extensions/extension_message_service.h" |
| 6 | 6 |
| 7 #include "base/atomic_sequence_num.h" | 7 #include "base/atomic_sequence_num.h" |
| 8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 #define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2) | 32 #define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2) |
| 33 #define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1) | 33 #define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1) |
| 34 | 34 |
| 35 // Port1 is always even, port2 is always odd. | 35 // Port1 is always even, port2 is always odd. |
| 36 #define IS_OPENER_PORT_ID(port_id) (((port_id) & 1) == 0) | 36 #define IS_OPENER_PORT_ID(port_id) (((port_id) & 1) == 0) |
| 37 | 37 |
| 38 // Change even to odd and vice versa, to get the other side of a given channel. | 38 // Change even to odd and vice versa, to get the other side of a given channel. |
| 39 #define GET_OPPOSITE_PORT_ID(source_port_id) ((source_port_id) ^ 1) | 39 #define GET_OPPOSITE_PORT_ID(source_port_id) ((source_port_id) ^ 1) |
| 40 | 40 |
| 41 struct ExtensionMessageService::MessagePort { | 41 struct ExtensionMessageService::MessagePort { |
| 42 IPC::Message::Sender* sender; | 42 content::RenderProcessHost* process; |
| 43 int routing_id; | 43 int routing_id; |
| 44 explicit MessagePort(IPC::Message::Sender* sender = NULL, | 44 explicit MessagePort(content::RenderProcessHost* process = NULL, |
| 45 int routing_id = MSG_ROUTING_CONTROL) | 45 int routing_id = MSG_ROUTING_CONTROL) |
| 46 : sender(sender), routing_id(routing_id) {} | 46 : process(process), routing_id(routing_id) {} |
| 47 }; | 47 }; |
| 48 | 48 |
| 49 struct ExtensionMessageService::MessageChannel { | 49 struct ExtensionMessageService::MessageChannel { |
| 50 ExtensionMessageService::MessagePort opener; | 50 ExtensionMessageService::MessagePort opener; |
| 51 ExtensionMessageService::MessagePort receiver; | 51 ExtensionMessageService::MessagePort receiver; |
| 52 }; | 52 }; |
| 53 | 53 |
| 54 const char ExtensionMessageService::kDispatchOnConnect[] = | 54 const char ExtensionMessageService::kDispatchOnConnect[] = |
| 55 "Port.dispatchOnConnect"; | 55 "Port.dispatchOnConnect"; |
| 56 const char ExtensionMessageService::kDispatchOnDisconnect[] = | 56 const char ExtensionMessageService::kDispatchOnDisconnect[] = |
| 57 "Port.dispatchOnDisconnect"; | 57 "Port.dispatchOnDisconnect"; |
| 58 | 58 |
| 59 namespace { | 59 namespace { |
| 60 | 60 |
| 61 static base::AtomicSequenceNumber g_next_channel_id(base::LINKER_INITIALIZED); | 61 static base::AtomicSequenceNumber g_next_channel_id(base::LINKER_INITIALIZED); |
| 62 | 62 |
| 63 static void DispatchOnConnect(const ExtensionMessageService::MessagePort& port, | 63 static void DispatchOnConnect(const ExtensionMessageService::MessagePort& port, |
| 64 int dest_port_id, | 64 int dest_port_id, |
| 65 const std::string& channel_name, | 65 const std::string& channel_name, |
| 66 const std::string& tab_json, | 66 const std::string& tab_json, |
| 67 const std::string& source_extension_id, | 67 const std::string& source_extension_id, |
| 68 const std::string& target_extension_id) { | 68 const std::string& target_extension_id) { |
| 69 ListValue args; | 69 ListValue args; |
| 70 args.Set(0, Value::CreateIntegerValue(dest_port_id)); | 70 args.Set(0, Value::CreateIntegerValue(dest_port_id)); |
| 71 args.Set(1, Value::CreateStringValue(channel_name)); | 71 args.Set(1, Value::CreateStringValue(channel_name)); |
| 72 args.Set(2, Value::CreateStringValue(tab_json)); | 72 args.Set(2, Value::CreateStringValue(tab_json)); |
| 73 args.Set(3, Value::CreateStringValue(source_extension_id)); | 73 args.Set(3, Value::CreateStringValue(source_extension_id)); |
| 74 args.Set(4, Value::CreateStringValue(target_extension_id)); | 74 args.Set(4, Value::CreateStringValue(target_extension_id)); |
| 75 CHECK(port.sender); | 75 CHECK(port.process); |
| 76 port.sender->Send( | 76 port.process->Send( |
| 77 new ExtensionMsg_MessageInvoke( | 77 new ExtensionMsg_MessageInvoke( |
| 78 port.routing_id, | 78 port.routing_id, |
| 79 target_extension_id, | 79 target_extension_id, |
| 80 ExtensionMessageService::kDispatchOnConnect, args, GURL(), | 80 ExtensionMessageService::kDispatchOnConnect, args, GURL(), |
| 81 false)); // Not a user gesture | 81 false)); // Not a user gesture |
| 82 } | 82 } |
| 83 | 83 |
| 84 static void DispatchOnDisconnect( | 84 static void DispatchOnDisconnect( |
| 85 const ExtensionMessageService::MessagePort& port, int source_port_id, | 85 const ExtensionMessageService::MessagePort& port, int source_port_id, |
| 86 bool connection_error) { | 86 bool connection_error) { |
| 87 ListValue args; | 87 ListValue args; |
| 88 args.Set(0, Value::CreateIntegerValue(source_port_id)); | 88 args.Set(0, Value::CreateIntegerValue(source_port_id)); |
| 89 args.Set(1, Value::CreateBooleanValue(connection_error)); | 89 args.Set(1, Value::CreateBooleanValue(connection_error)); |
| 90 port.sender->Send(new ExtensionMsg_MessageInvoke(port.routing_id, | 90 port.process->Send(new ExtensionMsg_MessageInvoke(port.routing_id, |
| 91 "", ExtensionMessageService::kDispatchOnDisconnect, args, GURL(), | 91 "", ExtensionMessageService::kDispatchOnDisconnect, args, GURL(), |
| 92 false)); // Not a user gesture | 92 false)); // Not a user gesture |
| 93 } | 93 } |
| 94 | 94 |
| 95 static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port, | 95 static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port, |
| 96 const std::string& message, int target_port_id) { | 96 const std::string& message, int target_port_id) { |
| 97 port.sender->Send( | 97 port.process->Send( |
| 98 new ExtensionMsg_DeliverMessage( | 98 new ExtensionMsg_DeliverMessage( |
| 99 port.routing_id, target_port_id, message)); | 99 port.routing_id, target_port_id, message)); |
| 100 } | 100 } |
| 101 | 101 |
| 102 static content::RenderProcessHost* GetExtensionProcess(Profile* profile, | 102 static content::RenderProcessHost* GetExtensionProcess(Profile* profile, |
| 103 const std::string& extension_id) { | 103 const std::string& extension_id) { |
| 104 SiteInstance* site_instance = | 104 SiteInstance* site_instance = |
| 105 profile->GetExtensionProcessManager()->GetSiteInstanceForURL( | 105 profile->GetExtensionProcessManager()->GetSiteInstanceForURL( |
| 106 Extension::GetBaseURLFromExtensionId(extension_id)); | 106 Extension::GetBaseURLFromExtensionId(extension_id)); |
| 107 | 107 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 125 DCHECK(GET_OPPOSITE_PORT_ID(port2_id) == port1_id); | 125 DCHECK(GET_OPPOSITE_PORT_ID(port2_id) == port1_id); |
| 126 DCHECK(GET_CHANNEL_ID(port1_id) == GET_CHANNEL_ID(port2_id)); | 126 DCHECK(GET_CHANNEL_ID(port1_id) == GET_CHANNEL_ID(port2_id)); |
| 127 DCHECK(GET_CHANNEL_ID(port1_id) == channel_id); | 127 DCHECK(GET_CHANNEL_ID(port1_id) == channel_id); |
| 128 DCHECK(GET_CHANNEL_OPENER_ID(channel_id) == port1_id); | 128 DCHECK(GET_CHANNEL_OPENER_ID(channel_id) == port1_id); |
| 129 DCHECK(GET_CHANNEL_RECEIVERS_ID(channel_id) == port2_id); | 129 DCHECK(GET_CHANNEL_RECEIVERS_ID(channel_id) == port2_id); |
| 130 | 130 |
| 131 *port1 = port1_id; | 131 *port1 = port1_id; |
| 132 *port2 = port2_id; | 132 *port2 = port2_id; |
| 133 } | 133 } |
| 134 | 134 |
| 135 ExtensionMessageService::ExtensionMessageService(Profile* profile) | 135 ExtensionMessageService::ExtensionMessageService(Profile* profile) { |
|
Yoyo Zhou
2012/03/10 01:36:54
Apparently you no longer need this argument.
| |
| 136 : profile_(profile) { | |
| 137 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 136 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| 138 content::NotificationService::AllBrowserContextsAndSources()); | 137 content::NotificationService::AllBrowserContextsAndSources()); |
| 139 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | 138 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| 140 content::NotificationService::AllBrowserContextsAndSources()); | 139 content::NotificationService::AllBrowserContextsAndSources()); |
| 141 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_DELETED, | |
| 142 content::NotificationService::AllBrowserContextsAndSources()); | |
| 143 } | 140 } |
| 144 | 141 |
| 145 ExtensionMessageService::~ExtensionMessageService() { | 142 ExtensionMessageService::~ExtensionMessageService() { |
| 146 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); | 143 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); |
| 147 channels_.clear(); | 144 channels_.clear(); |
| 148 } | 145 } |
| 149 | 146 |
| 150 void ExtensionMessageService::DestroyingProfile() { | |
| 151 profile_ = NULL; | |
| 152 if (!registrar_.IsEmpty()) | |
| 153 registrar_.RemoveAll(); | |
| 154 } | |
| 155 | |
| 156 void ExtensionMessageService::OpenChannelToExtension( | 147 void ExtensionMessageService::OpenChannelToExtension( |
| 157 int source_process_id, int source_routing_id, int receiver_port_id, | 148 int source_process_id, int source_routing_id, int receiver_port_id, |
| 158 const std::string& source_extension_id, | 149 const std::string& source_extension_id, |
| 159 const std::string& target_extension_id, | 150 const std::string& target_extension_id, |
| 160 const std::string& channel_name) { | 151 const std::string& channel_name) { |
| 161 content::RenderProcessHost* source = | 152 content::RenderProcessHost* source = |
| 162 content::RenderProcessHost::FromID(source_process_id); | 153 content::RenderProcessHost::FromID(source_process_id); |
| 163 if (!source) | 154 if (!source) |
| 164 return; | 155 return; |
| 165 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); | 156 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 192 content::RenderProcessHost* source = | 183 content::RenderProcessHost* source = |
| 193 content::RenderProcessHost::FromID(source_process_id); | 184 content::RenderProcessHost::FromID(source_process_id); |
| 194 if (!source) | 185 if (!source) |
| 195 return; | 186 return; |
| 196 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); | 187 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); |
| 197 | 188 |
| 198 TabContentsWrapper* contents = NULL; | 189 TabContentsWrapper* contents = NULL; |
| 199 MessagePort receiver; | 190 MessagePort receiver; |
| 200 if (ExtensionTabUtil::GetTabById(tab_id, profile, true, | 191 if (ExtensionTabUtil::GetTabById(tab_id, profile, true, |
| 201 NULL, NULL, &contents, NULL)) { | 192 NULL, NULL, &contents, NULL)) { |
| 202 receiver.sender = contents->web_contents()->GetRenderViewHost(); | 193 receiver.process = contents->web_contents()->GetRenderProcessHost(); |
| 203 receiver.routing_id = | 194 receiver.routing_id = |
| 204 contents->web_contents()->GetRenderViewHost()->GetRoutingID(); | 195 contents->web_contents()->GetRenderViewHost()->GetRoutingID(); |
| 205 } | 196 } |
| 206 | 197 |
| 207 if (contents && contents->web_contents()->GetController().NeedsReload()) { | 198 if (contents && contents->web_contents()->GetController().NeedsReload()) { |
| 208 // The tab isn't loaded yet. Don't attempt to connect. Treat this as a | 199 // The tab isn't loaded yet. Don't attempt to connect. Treat this as a |
| 209 // disconnect. | 200 // disconnect. |
| 210 DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL), | 201 DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL), |
| 211 GET_OPPOSITE_PORT_ID(receiver_port_id), true); | 202 GET_OPPOSITE_PORT_ID(receiver_port_id), true); |
| 212 return; | 203 return; |
| 213 } | 204 } |
| 214 | 205 |
| 215 WebContents* source_contents = tab_util::GetWebContentsByID( | 206 WebContents* source_contents = tab_util::GetWebContentsByID( |
| 216 source_process_id, source_routing_id); | 207 source_process_id, source_routing_id); |
| 217 | 208 |
| 218 // Include info about the opener's tab (if it was a tab). | 209 // Include info about the opener's tab (if it was a tab). |
| 219 std::string tab_json = "null"; | 210 std::string tab_json = "null"; |
| 220 if (source_contents) { | 211 if (source_contents) { |
| 221 scoped_ptr<DictionaryValue> tab_value( | 212 scoped_ptr<DictionaryValue> tab_value( |
| 222 ExtensionTabUtil::CreateTabValue(source_contents)); | 213 ExtensionTabUtil::CreateTabValue(source_contents)); |
| 223 base::JSONWriter::Write(tab_value.get(), false, &tab_json); | 214 base::JSONWriter::Write(tab_value.get(), false, &tab_json); |
| 224 } | 215 } |
| 225 | 216 |
| 226 OpenChannelImpl(source, tab_json, receiver, receiver_port_id, | 217 OpenChannelImpl(source, tab_json, receiver, receiver_port_id, |
| 227 extension_id, extension_id, channel_name); | 218 extension_id, extension_id, channel_name); |
| 228 } | 219 } |
| 229 | 220 |
| 230 bool ExtensionMessageService::OpenChannelImpl( | 221 bool ExtensionMessageService::OpenChannelImpl( |
| 231 IPC::Message::Sender* source, | 222 content::RenderProcessHost* source, |
| 232 const std::string& tab_json, | 223 const std::string& tab_json, |
| 233 const MessagePort& receiver, int receiver_port_id, | 224 const MessagePort& receiver, int receiver_port_id, |
| 234 const std::string& source_extension_id, | 225 const std::string& source_extension_id, |
| 235 const std::string& target_extension_id, | 226 const std::string& target_extension_id, |
| 236 const std::string& channel_name) { | 227 const std::string& channel_name) { |
| 237 if (!source) | 228 if (!source) |
| 238 return false; // Closed while in flight. | 229 return false; // Closed while in flight. |
| 239 | 230 |
| 240 if (!receiver.sender) { | 231 if (!receiver.process) { |
| 241 // Treat it as a disconnect. | 232 // Treat it as a disconnect. |
| 242 DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL), | 233 DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL), |
| 243 GET_OPPOSITE_PORT_ID(receiver_port_id), true); | 234 GET_OPPOSITE_PORT_ID(receiver_port_id), true); |
| 244 return false; | 235 return false; |
| 245 } | 236 } |
| 246 | 237 |
| 247 // Add extra paranoid CHECKs, since we have crash reports of this being NULL. | 238 // Add extra paranoid CHECKs, since we have crash reports of this being NULL. |
| 248 // http://code.google.com/p/chromium/issues/detail?id=19067 | 239 // http://code.google.com/p/chromium/issues/detail?id=19067 |
| 249 CHECK(receiver.sender); | 240 CHECK(receiver.process); |
| 250 | 241 |
| 251 MessageChannel* channel(new MessageChannel); | 242 MessageChannel* channel(new MessageChannel); |
| 252 channel->opener = MessagePort(source, MSG_ROUTING_CONTROL); | 243 channel->opener = MessagePort(source, MSG_ROUTING_CONTROL); |
| 253 channel->receiver = receiver; | 244 channel->receiver = receiver; |
| 254 | 245 |
| 255 CHECK(receiver.sender); | 246 CHECK(receiver.process); |
| 256 | 247 |
| 257 CHECK(channels_.find(GET_CHANNEL_ID(receiver_port_id)) == channels_.end()); | 248 CHECK(channels_.find(GET_CHANNEL_ID(receiver_port_id)) == channels_.end()); |
| 258 channels_[GET_CHANNEL_ID(receiver_port_id)] = channel; | 249 channels_[GET_CHANNEL_ID(receiver_port_id)] = channel; |
| 259 | 250 |
| 260 CHECK(receiver.sender); | 251 CHECK(receiver.process); |
| 261 | 252 |
| 262 // Send the connect event to the receiver. Give it the opener's port ID (the | 253 // Send the connect event to the receiver. Give it the opener's port ID (the |
| 263 // opener has the opposite port ID). | 254 // opener has the opposite port ID). |
| 264 DispatchOnConnect(receiver, receiver_port_id, channel_name, tab_json, | 255 DispatchOnConnect(receiver, receiver_port_id, channel_name, tab_json, |
| 265 source_extension_id, target_extension_id); | 256 source_extension_id, target_extension_id); |
| 266 | 257 |
| 267 return true; | 258 return true; |
| 268 } | 259 } |
| 269 | 260 |
| 270 int ExtensionMessageService::OpenSpecialChannelToExtension( | |
| 271 const std::string& extension_id, const std::string& channel_name, | |
| 272 const std::string& tab_json, IPC::Message::Sender* source) { | |
| 273 DCHECK(profile_); | |
| 274 | |
| 275 int port1_id = -1; | |
| 276 int port2_id = -1; | |
| 277 // Create a channel ID for both sides of the channel. | |
| 278 AllocatePortIdPair(&port1_id, &port2_id); | |
| 279 | |
| 280 MessagePort receiver( | |
| 281 GetExtensionProcess(profile_, extension_id), | |
| 282 MSG_ROUTING_CONTROL); | |
| 283 if (!OpenChannelImpl(source, tab_json, receiver, port2_id, | |
| 284 extension_id, extension_id, channel_name)) | |
| 285 return -1; | |
| 286 | |
| 287 return port1_id; | |
| 288 } | |
| 289 | |
| 290 int ExtensionMessageService::OpenSpecialChannelToTab( | |
| 291 const std::string& extension_id, const std::string& channel_name, | |
| 292 WebContents* target_web_contents, IPC::Message::Sender* source) { | |
| 293 DCHECK(target_web_contents); | |
| 294 | |
| 295 if (target_web_contents->GetController().NeedsReload()) { | |
| 296 // The tab isn't loaded yet. Don't attempt to connect. | |
| 297 return -1; | |
| 298 } | |
| 299 | |
| 300 int port1_id = -1; | |
| 301 int port2_id = -1; | |
| 302 // Create a channel ID for both sides of the channel. | |
| 303 AllocatePortIdPair(&port1_id, &port2_id); | |
| 304 | |
| 305 MessagePort receiver( | |
| 306 target_web_contents->GetRenderViewHost(), | |
| 307 target_web_contents->GetRenderViewHost()->GetRoutingID()); | |
| 308 if (!OpenChannelImpl(source, "null", receiver, port2_id, | |
| 309 extension_id, extension_id, channel_name)) | |
| 310 return -1; | |
| 311 | |
| 312 return port1_id; | |
| 313 } | |
| 314 | |
| 315 void ExtensionMessageService::CloseChannel(int port_id) { | 261 void ExtensionMessageService::CloseChannel(int port_id) { |
| 316 // Note: The channel might be gone already, if the other side closed first. | 262 // Note: The channel might be gone already, if the other side closed first. |
| 317 MessageChannelMap::iterator it = channels_.find(GET_CHANNEL_ID(port_id)); | 263 MessageChannelMap::iterator it = channels_.find(GET_CHANNEL_ID(port_id)); |
| 318 if (it != channels_.end()) | 264 if (it != channels_.end()) |
| 319 CloseChannelImpl(it, port_id, true); | 265 CloseChannelImpl(it, port_id, true); |
| 320 } | 266 } |
| 321 | 267 |
| 322 void ExtensionMessageService::CloseChannelImpl( | 268 void ExtensionMessageService::CloseChannelImpl( |
| 323 MessageChannelMap::iterator channel_iter, int closing_port_id, | 269 MessageChannelMap::iterator channel_iter, int closing_port_id, |
| 324 bool notify_other_port) { | 270 bool notify_other_port) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 339 if (iter == channels_.end()) | 285 if (iter == channels_.end()) |
| 340 return; | 286 return; |
| 341 | 287 |
| 342 // Figure out which port the ID corresponds to. | 288 // Figure out which port the ID corresponds to. |
| 343 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); | 289 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); |
| 344 const MessagePort& port = IS_OPENER_PORT_ID(dest_port_id) ? | 290 const MessagePort& port = IS_OPENER_PORT_ID(dest_port_id) ? |
| 345 iter->second->opener : iter->second->receiver; | 291 iter->second->opener : iter->second->receiver; |
| 346 | 292 |
| 347 DispatchOnMessage(port, message, dest_port_id); | 293 DispatchOnMessage(port, message, dest_port_id); |
| 348 } | 294 } |
| 295 | |
| 349 void ExtensionMessageService::Observe( | 296 void ExtensionMessageService::Observe( |
| 350 int type, | 297 int type, |
| 351 const content::NotificationSource& source, | 298 const content::NotificationSource& source, |
| 352 const content::NotificationDetails& details) { | 299 const content::NotificationDetails& details) { |
| 353 switch (type) { | 300 switch (type) { |
| 354 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: | 301 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: |
| 355 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { | 302 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { |
| 356 content::RenderProcessHost* renderer = | 303 content::RenderProcessHost* renderer = |
| 357 content::Source<content::RenderProcessHost>(source).ptr(); | 304 content::Source<content::RenderProcessHost>(source).ptr(); |
| 358 OnSenderClosed(renderer); | 305 OnProcessClosed(renderer); |
| 359 break; | 306 break; |
| 360 } | 307 } |
| 361 case content::NOTIFICATION_RENDER_VIEW_HOST_DELETED: | |
| 362 OnSenderClosed(content::Source<content::RenderViewHost>(source).ptr()); | |
| 363 break; | |
| 364 default: | 308 default: |
| 365 NOTREACHED(); | 309 NOTREACHED(); |
| 366 return; | 310 return; |
| 367 } | 311 } |
| 368 } | 312 } |
| 369 | 313 |
| 370 void ExtensionMessageService::OnSenderClosed(IPC::Message::Sender* sender) { | 314 void ExtensionMessageService::OnProcessClosed( |
| 315 content::RenderProcessHost* process) { | |
| 371 // Close any channels that share this renderer. We notify the opposite | 316 // Close any channels that share this renderer. We notify the opposite |
| 372 // port that his pair has closed. | 317 // port that his pair has closed. |
| 373 for (MessageChannelMap::iterator it = channels_.begin(); | 318 for (MessageChannelMap::iterator it = channels_.begin(); |
| 374 it != channels_.end(); ) { | 319 it != channels_.end(); ) { |
| 375 MessageChannelMap::iterator current = it++; | 320 MessageChannelMap::iterator current = it++; |
| 376 // If both sides are the same renderer, and it is closing, there is no | 321 // If both sides are the same renderer, and it is closing, there is no |
| 377 // "other" port, so there's no need to notify it. | 322 // "other" port, so there's no need to notify it. |
| 378 bool notify_other_port = | 323 bool notify_other_port = |
| 379 current->second->opener.sender != current->second->receiver.sender; | 324 current->second->opener.process != current->second->receiver.process; |
| 380 | 325 |
| 381 if (current->second->opener.sender == sender) { | 326 if (current->second->opener.process == process) { |
| 382 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), | 327 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), |
| 383 notify_other_port); | 328 notify_other_port); |
| 384 } else if (current->second->receiver.sender == sender) { | 329 } else if (current->second->receiver.process == process) { |
| 385 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), | 330 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), |
| 386 notify_other_port); | 331 notify_other_port); |
| 387 } | 332 } |
| 388 } | 333 } |
| 389 } | 334 } |
| OLD | NEW |