| 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/api/messaging/message_service.h" | 5 #include "chrome/browser/extensions/api/messaging/message_service.h" |
| 6 | 6 |
| 7 #include "base/atomic_sequence_num.h" | 7 #include "base/atomic_sequence_num.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
| 11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/prefs/pref_service.h" | 13 #include "base/prefs/pref_service.h" |
| 14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 15 #include "chrome/browser/chrome_notification_types.h" | |
| 16 #include "chrome/browser/extensions/api/messaging/extension_message_port.h" | 15 #include "chrome/browser/extensions/api/messaging/extension_message_port.h" |
| 17 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" | 16 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" |
| 18 #include "chrome/browser/extensions/api/messaging/native_message_port.h" | 17 #include "chrome/browser/extensions/api/messaging/native_message_port.h" |
| 19 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" | 18 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" |
| 20 #include "chrome/browser/extensions/extension_service.h" | 19 #include "chrome/browser/extensions/extension_service.h" |
| 21 #include "chrome/browser/extensions/extension_tab_util.h" | 20 #include "chrome/browser/extensions/extension_tab_util.h" |
| 22 #include "chrome/browser/extensions/extension_util.h" | 21 #include "chrome/browser/extensions/extension_util.h" |
| 23 #include "chrome/browser/profiles/profile.h" | 22 #include "chrome/browser/profiles/profile.h" |
| 24 #include "chrome/browser/tab_contents/tab_util.h" | 23 #include "chrome/browser/tab_contents/tab_util.h" |
| 25 #include "components/guest_view/common/guest_view_constants.h" | 24 #include "components/guest_view/common/guest_view_constants.h" |
| 26 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
| 27 #include "content/public/browser/notification_service.h" | |
| 28 #include "content/public/browser/render_frame_host.h" | 26 #include "content/public/browser/render_frame_host.h" |
| 29 #include "content/public/browser/render_process_host.h" | 27 #include "content/public/browser/render_process_host.h" |
| 30 #include "content/public/browser/render_view_host.h" | 28 #include "content/public/browser/render_view_host.h" |
| 31 #include "content/public/browser/render_widget_host.h" | 29 #include "content/public/browser/render_widget_host.h" |
| 32 #include "content/public/browser/render_widget_host_view.h" | 30 #include "content/public/browser/render_widget_host_view.h" |
| 33 #include "content/public/browser/site_instance.h" | 31 #include "content/public/browser/site_instance.h" |
| 34 #include "content/public/browser/web_contents.h" | 32 #include "content/public/browser/web_contents.h" |
| 35 #include "content/public/common/child_process_host.h" | 33 #include "content/public/common/child_process_host.h" |
| 36 #include "extensions/browser/event_router.h" | 34 #include "extensions/browser/event_router.h" |
| 37 #include "extensions/browser/extension_host.h" | 35 #include "extensions/browser/extension_host.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 "administrator."; | 119 "administrator."; |
| 122 #endif | 120 #endif |
| 123 | 121 |
| 124 struct MessageService::MessageChannel { | 122 struct MessageService::MessageChannel { |
| 125 scoped_ptr<MessagePort> opener; | 123 scoped_ptr<MessagePort> opener; |
| 126 scoped_ptr<MessagePort> receiver; | 124 scoped_ptr<MessagePort> receiver; |
| 127 }; | 125 }; |
| 128 | 126 |
| 129 struct MessageService::OpenChannelParams { | 127 struct MessageService::OpenChannelParams { |
| 130 int source_process_id; | 128 int source_process_id; |
| 129 int source_routing_id; |
| 131 scoped_ptr<base::DictionaryValue> source_tab; | 130 scoped_ptr<base::DictionaryValue> source_tab; |
| 132 int source_frame_id; | 131 int source_frame_id; |
| 133 int target_tab_id; | |
| 134 int target_frame_id; | |
| 135 scoped_ptr<MessagePort> receiver; | 132 scoped_ptr<MessagePort> receiver; |
| 136 int receiver_port_id; | 133 int receiver_port_id; |
| 137 std::string source_extension_id; | 134 std::string source_extension_id; |
| 138 std::string target_extension_id; | 135 std::string target_extension_id; |
| 139 GURL source_url; | 136 GURL source_url; |
| 140 std::string channel_name; | 137 std::string channel_name; |
| 141 bool include_tls_channel_id; | 138 bool include_tls_channel_id; |
| 142 std::string tls_channel_id; | 139 std::string tls_channel_id; |
| 143 bool include_guest_process_info; | 140 bool include_guest_process_info; |
| 144 | 141 |
| 145 // Takes ownership of receiver. | 142 // Takes ownership of receiver. |
| 146 OpenChannelParams(int source_process_id, | 143 OpenChannelParams(int source_process_id, |
| 144 int source_routing_id, |
| 147 scoped_ptr<base::DictionaryValue> source_tab, | 145 scoped_ptr<base::DictionaryValue> source_tab, |
| 148 int source_frame_id, | 146 int source_frame_id, |
| 149 int target_tab_id, | |
| 150 int target_frame_id, | |
| 151 MessagePort* receiver, | 147 MessagePort* receiver, |
| 152 int receiver_port_id, | 148 int receiver_port_id, |
| 153 const std::string& source_extension_id, | 149 const std::string& source_extension_id, |
| 154 const std::string& target_extension_id, | 150 const std::string& target_extension_id, |
| 155 const GURL& source_url, | 151 const GURL& source_url, |
| 156 const std::string& channel_name, | 152 const std::string& channel_name, |
| 157 bool include_tls_channel_id, | 153 bool include_tls_channel_id, |
| 158 bool include_guest_process_info) | 154 bool include_guest_process_info) |
| 159 : source_process_id(source_process_id), | 155 : source_process_id(source_process_id), |
| 156 source_routing_id(source_routing_id), |
| 160 source_frame_id(source_frame_id), | 157 source_frame_id(source_frame_id), |
| 161 target_tab_id(target_tab_id), | |
| 162 target_frame_id(target_frame_id), | |
| 163 receiver(receiver), | 158 receiver(receiver), |
| 164 receiver_port_id(receiver_port_id), | 159 receiver_port_id(receiver_port_id), |
| 165 source_extension_id(source_extension_id), | 160 source_extension_id(source_extension_id), |
| 166 target_extension_id(target_extension_id), | 161 target_extension_id(target_extension_id), |
| 167 source_url(source_url), | 162 source_url(source_url), |
| 168 channel_name(channel_name), | 163 channel_name(channel_name), |
| 169 include_tls_channel_id(include_tls_channel_id), | 164 include_tls_channel_id(include_tls_channel_id), |
| 170 include_guest_process_info(include_guest_process_info) { | 165 include_guest_process_info(include_guest_process_info) { |
| 171 if (source_tab) | 166 if (source_tab) |
| 172 this->source_tab = source_tab.Pass(); | 167 this->source_tab = source_tab.Pass(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 184 BrowserContext* context, | 179 BrowserContext* context, |
| 185 const std::string& extension_id) { | 180 const std::string& extension_id) { |
| 186 scoped_refptr<SiteInstance> site_instance = | 181 scoped_refptr<SiteInstance> site_instance = |
| 187 ProcessManager::Get(context)->GetSiteInstanceForURL( | 182 ProcessManager::Get(context)->GetSiteInstanceForURL( |
| 188 Extension::GetBaseURLFromExtensionId(extension_id)); | 183 Extension::GetBaseURLFromExtensionId(extension_id)); |
| 189 return site_instance->HasProcess() ? site_instance->GetProcess() : NULL; | 184 return site_instance->HasProcess() ? site_instance->GetProcess() : NULL; |
| 190 } | 185 } |
| 191 | 186 |
| 192 } // namespace | 187 } // namespace |
| 193 | 188 |
| 194 content::RenderProcessHost* | |
| 195 MessageService::MessagePort::GetRenderProcessHost() { | |
| 196 return NULL; | |
| 197 } | |
| 198 | |
| 199 // static | 189 // static |
| 200 void MessageService::AllocatePortIdPair(int* port1, int* port2) { | 190 void MessageService::AllocatePortIdPair(int* port1, int* port2) { |
| 201 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 191 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 202 | 192 |
| 203 unsigned channel_id = | 193 unsigned channel_id = |
| 204 static_cast<unsigned>(g_next_channel_id.GetNext()) % (kint32max/2); | 194 static_cast<unsigned>(g_next_channel_id.GetNext()) % (kint32max/2); |
| 205 unsigned port1_id = channel_id * 2; | 195 unsigned port1_id = channel_id * 2; |
| 206 unsigned port2_id = channel_id * 2 + 1; | 196 unsigned port2_id = channel_id * 2 + 1; |
| 207 | 197 |
| 208 // Sanity checks to make sure our channel<->port converters are correct. | 198 // Sanity checks to make sure our channel<->port converters are correct. |
| 209 DCHECK(IS_OPENER_PORT_ID(port1_id)); | 199 DCHECK(IS_OPENER_PORT_ID(port1_id)); |
| 210 DCHECK_EQ(GET_OPPOSITE_PORT_ID(port1_id), port2_id); | 200 DCHECK_EQ(GET_OPPOSITE_PORT_ID(port1_id), port2_id); |
| 211 DCHECK_EQ(GET_OPPOSITE_PORT_ID(port2_id), port1_id); | 201 DCHECK_EQ(GET_OPPOSITE_PORT_ID(port2_id), port1_id); |
| 212 DCHECK_EQ(GET_CHANNEL_ID(port1_id), GET_CHANNEL_ID(port2_id)); | 202 DCHECK_EQ(GET_CHANNEL_ID(port1_id), GET_CHANNEL_ID(port2_id)); |
| 213 DCHECK_EQ(GET_CHANNEL_ID(port1_id), channel_id); | 203 DCHECK_EQ(GET_CHANNEL_ID(port1_id), channel_id); |
| 214 DCHECK_EQ(GET_CHANNEL_OPENER_ID(channel_id), port1_id); | 204 DCHECK_EQ(GET_CHANNEL_OPENER_ID(channel_id), port1_id); |
| 215 DCHECK_EQ(GET_CHANNEL_RECEIVERS_ID(channel_id), port2_id); | 205 DCHECK_EQ(GET_CHANNEL_RECEIVERS_ID(channel_id), port2_id); |
| 216 | 206 |
| 217 *port1 = port1_id; | 207 *port1 = port1_id; |
| 218 *port2 = port2_id; | 208 *port2 = port2_id; |
| 219 } | 209 } |
| 220 | 210 |
| 221 MessageService::MessageService(BrowserContext* context) | 211 MessageService::MessageService(BrowserContext* context) |
| 222 : lazy_background_task_queue_( | 212 : lazy_background_task_queue_( |
| 223 LazyBackgroundTaskQueue::Get(context)), | 213 LazyBackgroundTaskQueue::Get(context)), |
| 224 weak_factory_(this) { | 214 weak_factory_(this) { |
| 225 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 215 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 226 | |
| 227 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | |
| 228 content::NotificationService::AllBrowserContextsAndSources()); | |
| 229 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | |
| 230 content::NotificationService::AllBrowserContextsAndSources()); | |
| 231 } | 216 } |
| 232 | 217 |
| 233 MessageService::~MessageService() { | 218 MessageService::~MessageService() { |
| 234 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 219 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 235 | 220 |
| 236 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); | 221 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); |
| 237 channels_.clear(); | 222 channels_.clear(); |
| 238 } | 223 } |
| 239 | 224 |
| 240 static base::LazyInstance<BrowserContextKeyedAPIFactory<MessageService> > | 225 static base::LazyInstance<BrowserContextKeyedAPIFactory<MessageService> > |
| (...skipping 12 matching lines...) Expand all Loading... |
| 253 | 238 |
| 254 void MessageService::OpenChannelToExtension( | 239 void MessageService::OpenChannelToExtension( |
| 255 int source_process_id, int source_routing_id, int receiver_port_id, | 240 int source_process_id, int source_routing_id, int receiver_port_id, |
| 256 const std::string& source_extension_id, | 241 const std::string& source_extension_id, |
| 257 const std::string& target_extension_id, | 242 const std::string& target_extension_id, |
| 258 const GURL& source_url, | 243 const GURL& source_url, |
| 259 const std::string& channel_name, | 244 const std::string& channel_name, |
| 260 bool include_tls_channel_id) { | 245 bool include_tls_channel_id) { |
| 261 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 246 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 262 | 247 |
| 263 content::RenderProcessHost* source = | 248 content::RenderFrameHost* source = |
| 264 content::RenderProcessHost::FromID(source_process_id); | 249 content::RenderFrameHost::FromID(source_process_id, source_routing_id); |
| 265 if (!source) | 250 if (!source) |
| 266 return; | 251 return; |
| 267 BrowserContext* context = source->GetBrowserContext(); | 252 BrowserContext* context = source->GetProcess()->GetBrowserContext(); |
| 268 | 253 |
| 269 ExtensionRegistry* registry = ExtensionRegistry::Get(context); | 254 ExtensionRegistry* registry = ExtensionRegistry::Get(context); |
| 270 const Extension* target_extension = | 255 const Extension* target_extension = |
| 271 registry->enabled_extensions().GetByID(target_extension_id); | 256 registry->enabled_extensions().GetByID(target_extension_id); |
| 272 if (!target_extension) { | 257 if (!target_extension) { |
| 273 DispatchOnDisconnect( | 258 DispatchOnDisconnect( |
| 274 source, receiver_port_id, kReceivingEndDoesntExistError); | 259 source, receiver_port_id, kReceivingEndDoesntExistError); |
| 275 return; | 260 return; |
| 276 } | 261 } |
| 277 | 262 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 if (source_contents && ExtensionTabUtil::GetTabId(source_contents) >= 0) { | 315 if (source_contents && ExtensionTabUtil::GetTabId(source_contents) >= 0) { |
| 331 // Only the tab id is useful to platform apps for internal use. The | 316 // Only the tab id is useful to platform apps for internal use. The |
| 332 // unnecessary bits will be stripped out in | 317 // unnecessary bits will be stripped out in |
| 333 // MessagingBindings::DispatchOnConnect(). | 318 // MessagingBindings::DispatchOnConnect(). |
| 334 source_tab.reset(ExtensionTabUtil::CreateTabValue(source_contents)); | 319 source_tab.reset(ExtensionTabUtil::CreateTabValue(source_contents)); |
| 335 | 320 |
| 336 content::RenderFrameHost* rfh = | 321 content::RenderFrameHost* rfh = |
| 337 content::RenderFrameHost::FromID(source_process_id, source_routing_id); | 322 content::RenderFrameHost::FromID(source_process_id, source_routing_id); |
| 338 // Main frame's frameId is 0. | 323 // Main frame's frameId is 0. |
| 339 if (rfh) | 324 if (rfh) |
| 340 source_frame_id = !rfh->GetParent() ? 0 : source_routing_id; | 325 source_frame_id = !rfh->GetParent() ? 0 : rfh->GetFrameTreeNodeID(); |
| 341 } else { | 326 } else { |
| 342 // Check to see if it was a WebView making the request. | 327 // Check to see if it was a WebView making the request. |
| 343 // Sending messages from WebViews to extensions breaks webview isolation, | 328 // Sending messages from WebViews to extensions breaks webview isolation, |
| 344 // so only allow component extensions to receive messages from WebViews. | 329 // so only allow component extensions to receive messages from WebViews. |
| 345 bool is_web_view = !!WebViewGuest::FromWebContents(source_contents); | 330 bool is_web_view = !!WebViewGuest::FromWebContents(source_contents); |
| 346 if (is_web_view && extensions::Manifest::IsComponentLocation( | 331 if (is_web_view && extensions::Manifest::IsComponentLocation( |
| 347 target_extension->location())) { | 332 target_extension->location())) { |
| 348 include_guest_process_info = true; | 333 include_guest_process_info = true; |
| 349 auto* rfh = content::RenderFrameHost::FromID(source_process_id, | |
| 350 source_routing_id); | |
| 351 // Include |source_frame_id| so that we can retrieve the guest's frame | |
| 352 // routing id in OpenChannelImpl. | |
| 353 if (rfh) | |
| 354 source_frame_id = source_routing_id; | |
| 355 } | 334 } |
| 356 } | 335 } |
| 357 | 336 |
| 358 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( | 337 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( |
| 359 source_process_id, source_tab.Pass(), source_frame_id, -1, | 338 source_process_id, source_routing_id, source_tab.Pass(), source_frame_id, |
| 360 -1, // no target_tab_id/target_frame_id for connections to extensions | |
| 361 nullptr, receiver_port_id, source_extension_id, target_extension_id, | 339 nullptr, receiver_port_id, source_extension_id, target_extension_id, |
| 362 source_url, channel_name, include_tls_channel_id, | 340 source_url, channel_name, include_tls_channel_id, |
| 363 include_guest_process_info)); | 341 include_guest_process_info)); |
| 364 | 342 |
| 365 pending_incognito_channels_[GET_CHANNEL_ID(params->receiver_port_id)] = | 343 pending_incognito_channels_[GET_CHANNEL_ID(params->receiver_port_id)] = |
| 366 PendingMessagesQueue(); | 344 PendingMessagesQueue(); |
| 367 if (context->IsOffTheRecord() && | 345 if (context->IsOffTheRecord() && |
| 368 !util::IsIncognitoEnabled(target_extension_id, context)) { | 346 !util::IsIncognitoEnabled(target_extension_id, context)) { |
| 369 // Give the user a chance to accept an incognito connection from the web if | 347 // Give the user a chance to accept an incognito connection from the web if |
| 370 // they haven't already, with the conditions: | 348 // they haven't already, with the conditions: |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 } | 388 } |
| 411 | 389 |
| 412 void MessageService::OpenChannelToNativeApp( | 390 void MessageService::OpenChannelToNativeApp( |
| 413 int source_process_id, | 391 int source_process_id, |
| 414 int source_routing_id, | 392 int source_routing_id, |
| 415 int receiver_port_id, | 393 int receiver_port_id, |
| 416 const std::string& source_extension_id, | 394 const std::string& source_extension_id, |
| 417 const std::string& native_app_name) { | 395 const std::string& native_app_name) { |
| 418 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 396 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 419 | 397 |
| 420 content::RenderProcessHost* source = | 398 content::RenderFrameHost* source = |
| 421 content::RenderProcessHost::FromID(source_process_id); | 399 content::RenderFrameHost::FromID(source_process_id, source_routing_id); |
| 422 if (!source) | 400 if (!source) |
| 423 return; | 401 return; |
| 424 | 402 |
| 425 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) | 403 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) |
| 426 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); | 404 Profile* profile = |
| 405 Profile::FromBrowserContext(source->GetProcess()->GetBrowserContext()); |
| 427 ExtensionService* extension_service = | 406 ExtensionService* extension_service = |
| 428 ExtensionSystem::Get(profile)->extension_service(); | 407 ExtensionSystem::Get(profile)->extension_service(); |
| 429 bool has_permission = false; | 408 bool has_permission = false; |
| 430 if (extension_service) { | 409 if (extension_service) { |
| 431 const Extension* extension = | 410 const Extension* extension = |
| 432 extension_service->GetExtensionById(source_extension_id, false); | 411 extension_service->GetExtensionById(source_extension_id, false); |
| 433 has_permission = extension && | 412 has_permission = extension && |
| 434 extension->permissions_data()->HasAPIPermission( | 413 extension->permissions_data()->HasAPIPermission( |
| 435 APIPermission::kNativeMessaging); | 414 APIPermission::kNativeMessaging); |
| 436 } | 415 } |
| 437 | 416 |
| 438 if (!has_permission) { | 417 if (!has_permission) { |
| 439 DispatchOnDisconnect(source, receiver_port_id, kMissingPermissionError); | 418 DispatchOnDisconnect(source, receiver_port_id, kMissingPermissionError); |
| 440 return; | 419 return; |
| 441 } | 420 } |
| 442 | 421 |
| 443 PrefService* pref_service = profile->GetPrefs(); | 422 PrefService* pref_service = profile->GetPrefs(); |
| 444 | 423 |
| 445 // Verify that the host is not blocked by policies. | 424 // Verify that the host is not blocked by policies. |
| 446 PolicyPermission policy_permission = | 425 PolicyPermission policy_permission = |
| 447 IsNativeMessagingHostAllowed(pref_service, native_app_name); | 426 IsNativeMessagingHostAllowed(pref_service, native_app_name); |
| 448 if (policy_permission == DISALLOW) { | 427 if (policy_permission == DISALLOW) { |
| 449 DispatchOnDisconnect(source, receiver_port_id, kProhibitedByPoliciesError); | 428 DispatchOnDisconnect(source, receiver_port_id, kProhibitedByPoliciesError); |
| 450 return; | 429 return; |
| 451 } | 430 } |
| 452 | 431 |
| 453 scoped_ptr<MessageChannel> channel(new MessageChannel()); | 432 scoped_ptr<MessageChannel> channel(new MessageChannel()); |
| 454 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, | 433 channel->opener.reset( |
| 455 source_extension_id)); | 434 new ExtensionMessagePort(weak_factory_.GetWeakPtr(), |
| 435 GET_OPPOSITE_PORT_ID(receiver_port_id), |
| 436 source_extension_id, source, false)); |
| 456 | 437 |
| 457 // Get handle of the native view and pass it to the native messaging host. | 438 // Get handle of the native view and pass it to the native messaging host. |
| 458 content::RenderFrameHost* render_frame_host = | 439 gfx::NativeView native_view = source ? source->GetNativeView() : nullptr; |
| 459 content::RenderFrameHost::FromID(source_process_id, source_routing_id); | |
| 460 gfx::NativeView native_view = | |
| 461 render_frame_host ? render_frame_host->GetNativeView() : nullptr; | |
| 462 | 440 |
| 463 std::string error = kReceivingEndDoesntExistError; | 441 std::string error = kReceivingEndDoesntExistError; |
| 464 scoped_ptr<NativeMessageHost> native_host = NativeMessageHost::Create( | 442 scoped_ptr<NativeMessageHost> native_host = NativeMessageHost::Create( |
| 465 native_view, | 443 native_view, |
| 466 source_extension_id, | 444 source_extension_id, |
| 467 native_app_name, | 445 native_app_name, |
| 468 policy_permission == ALLOW_ALL, | 446 policy_permission == ALLOW_ALL, |
| 469 &error); | 447 &error); |
| 470 | 448 |
| 471 // Abandon the channel. | 449 // Abandon the channel. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 483 AddChannel(channel.release(), receiver_port_id); | 461 AddChannel(channel.release(), receiver_port_id); |
| 484 #else // !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)) | 462 #else // !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)) |
| 485 const char kNativeMessagingNotSupportedError[] = | 463 const char kNativeMessagingNotSupportedError[] = |
| 486 "Native Messaging is not supported on this platform."; | 464 "Native Messaging is not supported on this platform."; |
| 487 DispatchOnDisconnect( | 465 DispatchOnDisconnect( |
| 488 source, receiver_port_id, kNativeMessagingNotSupportedError); | 466 source, receiver_port_id, kNativeMessagingNotSupportedError); |
| 489 #endif // !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)) | 467 #endif // !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)) |
| 490 } | 468 } |
| 491 | 469 |
| 492 void MessageService::OpenChannelToTab(int source_process_id, | 470 void MessageService::OpenChannelToTab(int source_process_id, |
| 471 int source_routing_id, |
| 493 int receiver_port_id, | 472 int receiver_port_id, |
| 494 int tab_id, | 473 int tab_id, |
| 495 int frame_id, | 474 int frame_id, |
| 496 const std::string& extension_id, | 475 const std::string& extension_id, |
| 497 const std::string& channel_name) { | 476 const std::string& channel_name) { |
| 498 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 477 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 478 DCHECK_GE(frame_id, -1); |
| 499 | 479 |
| 500 content::RenderProcessHost* source = | 480 content::RenderFrameHost* source = |
| 501 content::RenderProcessHost::FromID(source_process_id); | 481 content::RenderFrameHost::FromID(source_process_id, source_routing_id); |
| 502 if (!source) | 482 if (!source) |
| 503 return; | 483 return; |
| 504 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); | 484 Profile* profile = |
| 485 Profile::FromBrowserContext(source->GetProcess()->GetBrowserContext()); |
| 505 | 486 |
| 506 WebContents* contents = NULL; | 487 WebContents* contents = NULL; |
| 507 scoped_ptr<MessagePort> receiver; | 488 scoped_ptr<MessagePort> receiver; |
| 508 if (!ExtensionTabUtil::GetTabById(tab_id, profile, true, NULL, NULL, | 489 if (!ExtensionTabUtil::GetTabById(tab_id, profile, true, NULL, NULL, |
| 509 &contents, NULL) || | 490 &contents, NULL) || |
| 510 contents->GetController().NeedsReload()) { | 491 contents->GetController().NeedsReload()) { |
| 511 // The tab isn't loaded yet. Don't attempt to connect. | 492 // The tab isn't loaded yet. Don't attempt to connect. |
| 512 DispatchOnDisconnect( | 493 DispatchOnDisconnect( |
| 513 source, receiver_port_id, kReceivingEndDoesntExistError); | 494 source, receiver_port_id, kReceivingEndDoesntExistError); |
| 514 return; | 495 return; |
| 515 } | 496 } |
| 516 | 497 |
| 517 int receiver_routing_id; | 498 content::RenderFrameHost* receiver_rfh = contents->GetMainFrame(); |
| 499 if (!receiver_rfh) { |
| 500 DispatchOnDisconnect( |
| 501 source, receiver_port_id, kReceivingEndDoesntExistError); |
| 502 return; |
| 503 } |
| 504 // Frame ID 0 is main frame. |
| 505 // Frame ID -1 is every frame in the tab. |
| 506 bool include_child_frames = frame_id == -1; |
| 518 if (frame_id > 0) { | 507 if (frame_id > 0) { |
| 519 // Positive frame ID is child frame. | 508 // Positive frame ID is child frame. |
| 520 int receiver_process_id = contents->GetRenderProcessHost()->GetID(); | 509 receiver_rfh = receiver_rfh->FindByFrameTreeNodeID(frame_id); |
| 521 if (!content::RenderFrameHost::FromID(receiver_process_id, frame_id)) { | 510 if (!receiver_rfh) { |
| 522 // Frame does not exist. | |
| 523 DispatchOnDisconnect( | 511 DispatchOnDisconnect( |
| 524 source, receiver_port_id, kReceivingEndDoesntExistError); | 512 source, receiver_port_id, kReceivingEndDoesntExistError); |
| 525 return; | 513 return; |
| 526 } | 514 } |
| 527 receiver_routing_id = frame_id; | |
| 528 } else if (frame_id == 0) { | |
| 529 // Frame ID 0 is main frame. | |
| 530 receiver_routing_id = contents->GetMainFrame()->GetRoutingID(); | |
| 531 } else { | |
| 532 DCHECK_EQ(-1, frame_id); | |
| 533 // If the frame ID is not set (i.e. -1), then the channel has to be opened | |
| 534 // in every frame. | |
| 535 // TODO(robwu): Update logic so that frames that are not hosted in the main | |
| 536 // frame's process can also receive the port. | |
| 537 receiver_routing_id = MSG_ROUTING_CONTROL; | |
| 538 } | 515 } |
| 539 receiver.reset(new ExtensionMessagePort(contents->GetRenderProcessHost(), | 516 receiver.reset( |
| 540 receiver_routing_id, extension_id)); | 517 new ExtensionMessagePort(weak_factory_.GetWeakPtr(), |
| 518 receiver_port_id, extension_id, receiver_rfh, |
| 519 include_child_frames)); |
| 541 | 520 |
| 542 const Extension* extension = nullptr; | 521 const Extension* extension = nullptr; |
| 543 if (!extension_id.empty()) { | 522 if (!extension_id.empty()) { |
| 544 // Source extension == target extension so the extension must exist, or | 523 // Source extension == target extension so the extension must exist, or |
| 545 // where did the IPC come from? | 524 // where did the IPC come from? |
| 546 extension = ExtensionRegistry::Get(profile)->enabled_extensions().GetByID( | 525 extension = ExtensionRegistry::Get(profile)->enabled_extensions().GetByID( |
| 547 extension_id); | 526 extension_id); |
| 548 DCHECK(extension); | 527 DCHECK(extension); |
| 549 } | 528 } |
| 550 | 529 |
| 551 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( | 530 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( |
| 552 source_process_id, | 531 source_process_id, |
| 532 source_routing_id, |
| 553 scoped_ptr<base::DictionaryValue>(), // Source tab doesn't make sense | 533 scoped_ptr<base::DictionaryValue>(), // Source tab doesn't make sense |
| 554 // for opening to tabs. | 534 // for opening to tabs. |
| 555 -1, // If there is no tab, then there is no frame either. | 535 -1, // If there is no tab, then there is no frame either. |
| 556 tab_id, frame_id, receiver.release(), receiver_port_id, extension_id, | 536 receiver.release(), receiver_port_id, extension_id, extension_id, |
| 557 extension_id, | |
| 558 GURL(), // Source URL doesn't make sense for opening to tabs. | 537 GURL(), // Source URL doesn't make sense for opening to tabs. |
| 559 channel_name, | 538 channel_name, |
| 560 false, // Connections to tabs don't get TLS channel IDs. | 539 false, // Connections to tabs don't get TLS channel IDs. |
| 561 false)); // Connections to tabs aren't webview guests. | 540 false)); // Connections to tabs aren't webview guests. |
| 562 OpenChannelImpl(contents->GetBrowserContext(), params.Pass(), extension, | 541 OpenChannelImpl(contents->GetBrowserContext(), params.Pass(), extension, |
| 563 false /* did_enqueue */); | 542 false /* did_enqueue */); |
| 564 } | 543 } |
| 565 | 544 |
| 566 void MessageService::OpenChannelImpl(BrowserContext* browser_context, | 545 void MessageService::OpenChannelImpl(BrowserContext* browser_context, |
| 567 scoped_ptr<OpenChannelParams> params, | 546 scoped_ptr<OpenChannelParams> params, |
| 568 const Extension* target_extension, | 547 const Extension* target_extension, |
| 569 bool did_enqueue) { | 548 bool did_enqueue) { |
| 570 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 549 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 571 DCHECK_EQ(target_extension != nullptr, !params->target_extension_id.empty()); | 550 DCHECK_EQ(target_extension != nullptr, !params->target_extension_id.empty()); |
| 572 | 551 |
| 573 content::RenderProcessHost* source = | 552 content::RenderFrameHost* source = |
| 574 content::RenderProcessHost::FromID(params->source_process_id); | 553 content::RenderFrameHost::FromID(params->source_process_id, |
| 554 params->source_routing_id); |
| 575 if (!source) | 555 if (!source) |
| 576 return; // Closed while in flight. | 556 return; // Closed while in flight. |
| 577 | 557 |
| 578 if (!params->receiver || !params->receiver->GetRenderProcessHost()) { | 558 if (!params->receiver) { |
| 579 DispatchOnDisconnect(source, params->receiver_port_id, | 559 DispatchOnDisconnect(source, params->receiver_port_id, |
| 580 kReceivingEndDoesntExistError); | 560 kReceivingEndDoesntExistError); |
| 581 return; | 561 return; |
| 582 } | 562 } |
| 583 | 563 |
| 584 MessageChannel* channel(new MessageChannel); | 564 MessageChannel* channel(new MessageChannel); |
| 585 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, | 565 channel->opener.reset( |
| 586 params->source_extension_id)); | 566 new ExtensionMessagePort(weak_factory_.GetWeakPtr(), |
| 567 GET_OPPOSITE_PORT_ID(params->receiver_port_id), |
| 568 params->source_extension_id, source, false)); |
| 587 channel->receiver.reset(params->receiver.release()); | 569 channel->receiver.reset(params->receiver.release()); |
| 588 AddChannel(channel, params->receiver_port_id); | 570 AddChannel(channel, params->receiver_port_id); |
| 589 | 571 |
| 572 // TODO(robwu): Could |guest_process_id| and |guest_render_frame_routing_id| |
| 573 // be removed? In the past extension message routing was process-based, but |
| 574 // now that extensions are routed from a specific RFH, the special casing for |
| 575 // guest views seems no longer necessary, because the ExtensionMessagePort can |
| 576 // simply obtain the source process & frame ID directly from the RFH. |
| 590 int guest_process_id = content::ChildProcessHost::kInvalidUniqueID; | 577 int guest_process_id = content::ChildProcessHost::kInvalidUniqueID; |
| 591 int guest_render_frame_routing_id = MSG_ROUTING_NONE; | 578 int guest_render_frame_routing_id = MSG_ROUTING_NONE; |
| 592 if (params->include_guest_process_info) { | 579 if (params->include_guest_process_info) { |
| 593 guest_process_id = params->source_process_id; | 580 guest_process_id = params->source_process_id; |
| 594 guest_render_frame_routing_id = params->source_frame_id; | 581 guest_render_frame_routing_id = params->source_routing_id; |
| 595 auto* guest_rfh = content::RenderFrameHost::FromID( | |
| 596 guest_process_id, guest_render_frame_routing_id); | |
| 597 // Reset the |source_frame_id| parameter. | |
| 598 params->source_frame_id = -1; | |
| 599 | 582 |
| 600 DCHECK(guest_rfh == nullptr || | 583 DCHECK(WebViewGuest::FromWebContents( |
| 601 WebViewGuest::FromWebContents( | 584 WebContents::FromRenderFrameHost(source))); |
| 602 WebContents::FromRenderFrameHost(guest_rfh)) != nullptr); | |
| 603 } | 585 } |
| 604 | 586 |
| 605 // Send the connect event to the receiver. Give it the opener's port ID (the | 587 // Send the connect event to the receiver. Give it the opener's port ID (the |
| 606 // opener has the opposite port ID). | 588 // opener has the opposite port ID). |
| 607 channel->receiver->DispatchOnConnect( | 589 channel->receiver->DispatchOnConnect( |
| 608 params->receiver_port_id, params->channel_name, params->source_tab.Pass(), | 590 params->channel_name, params->source_tab.Pass(), params->source_frame_id, |
| 609 params->source_frame_id, params->target_tab_id, params->target_frame_id, | |
| 610 guest_process_id, guest_render_frame_routing_id, | 591 guest_process_id, guest_render_frame_routing_id, |
| 611 params->source_extension_id, params->target_extension_id, | 592 params->source_extension_id, params->target_extension_id, |
| 612 params->source_url, params->tls_channel_id); | 593 params->source_url, params->tls_channel_id); |
| 613 | 594 |
| 614 // Report the event to the event router, if the target is an extension. | 595 // Report the event to the event router, if the target is an extension. |
| 615 // | 596 // |
| 616 // First, determine what event this will be (runtime.onConnect vs | 597 // First, determine what event this will be (runtime.onConnect vs |
| 617 // runtime.onMessage etc), and what the event target is (view vs background | 598 // runtime.onMessage etc), and what the event target is (view vs background |
| 618 // page etc). | 599 // page etc). |
| 619 // | 600 // |
| (...skipping 29 matching lines...) Expand all Loading... |
| 649 | 630 |
| 650 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) { | 631 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) { |
| 651 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 632 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 652 | 633 |
| 653 int channel_id = GET_CHANNEL_ID(receiver_port_id); | 634 int channel_id = GET_CHANNEL_ID(receiver_port_id); |
| 654 CHECK(channels_.find(channel_id) == channels_.end()); | 635 CHECK(channels_.find(channel_id) == channels_.end()); |
| 655 channels_[channel_id] = channel; | 636 channels_[channel_id] = channel; |
| 656 pending_lazy_background_page_channels_.erase(channel_id); | 637 pending_lazy_background_page_channels_.erase(channel_id); |
| 657 } | 638 } |
| 658 | 639 |
| 640 void MessageService::OpenPort(int port_id, int process_id, int routing_id) { |
| 641 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 642 DCHECK(!IS_OPENER_PORT_ID(port_id)); |
| 643 |
| 644 int channel_id = GET_CHANNEL_ID(port_id); |
| 645 MessageChannelMap::iterator it = channels_.find(channel_id); |
| 646 if (it == channels_.end()) |
| 647 return; |
| 648 |
| 649 it->second->receiver->OpenPort(process_id, routing_id); |
| 650 } |
| 651 |
| 652 void MessageService::ClosePort( |
| 653 int port_id, int process_id, int routing_id, bool force_close) { |
| 654 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 655 |
| 656 if (force_close) { |
| 657 CloseChannel(port_id, std::string()); |
| 658 return; |
| 659 } |
| 660 |
| 661 int channel_id = GET_CHANNEL_ID(port_id); |
| 662 MessageChannelMap::iterator it = channels_.find(channel_id); |
| 663 if (it == channels_.end()) |
| 664 return; |
| 665 |
| 666 if (IS_OPENER_PORT_ID(port_id)) { |
| 667 it->second->opener->ClosePort(process_id, routing_id); |
| 668 } else { |
| 669 it->second->receiver->ClosePort(process_id, routing_id); |
| 670 } |
| 671 } |
| 672 |
| 659 void MessageService::CloseChannel(int port_id, | 673 void MessageService::CloseChannel(int port_id, |
| 660 const std::string& error_message) { | 674 const std::string& error_message) { |
| 661 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 675 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 662 | 676 |
| 663 // Note: The channel might be gone already, if the other side closed first. | 677 // Note: The channel might be gone already, if the other side closed first. |
| 664 int channel_id = GET_CHANNEL_ID(port_id); | 678 int channel_id = GET_CHANNEL_ID(port_id); |
| 665 MessageChannelMap::iterator it = channels_.find(channel_id); | 679 MessageChannelMap::iterator it = channels_.find(channel_id); |
| 666 if (it == channels_.end()) { | 680 if (it == channels_.end()) { |
| 667 PendingLazyBackgroundPageChannelMap::iterator pending = | 681 PendingLazyBackgroundPageChannelMap::iterator pending = |
| 668 pending_lazy_background_page_channels_.find(channel_id); | 682 pending_lazy_background_page_channels_.find(channel_id); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 683 const std::string& error_message, | 697 const std::string& error_message, |
| 684 bool notify_other_port) { | 698 bool notify_other_port) { |
| 685 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 699 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 686 | 700 |
| 687 MessageChannel* channel = channel_iter->second; | 701 MessageChannel* channel = channel_iter->second; |
| 688 | 702 |
| 689 // Notify the other side. | 703 // Notify the other side. |
| 690 if (notify_other_port) { | 704 if (notify_other_port) { |
| 691 MessagePort* port = IS_OPENER_PORT_ID(closing_port_id) ? | 705 MessagePort* port = IS_OPENER_PORT_ID(closing_port_id) ? |
| 692 channel->receiver.get() : channel->opener.get(); | 706 channel->receiver.get() : channel->opener.get(); |
| 693 port->DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(closing_port_id), | 707 port->DispatchOnDisconnect(error_message); |
| 694 error_message); | |
| 695 } | 708 } |
| 696 | 709 |
| 697 // Balance the IncrementLazyKeepaliveCount() in OpenChannelImpl. | 710 // Balance the IncrementLazyKeepaliveCount() in OpenChannelImpl. |
| 698 channel->opener->DecrementLazyKeepaliveCount(); | 711 channel->opener->DecrementLazyKeepaliveCount(); |
| 699 channel->receiver->DecrementLazyKeepaliveCount(); | 712 channel->receiver->DecrementLazyKeepaliveCount(); |
| 700 | 713 |
| 701 delete channel_iter->second; | 714 delete channel_iter->second; |
| 702 channels_.erase(channel_iter); | 715 channels_.erase(channel_iter); |
| 703 } | 716 } |
| 704 | 717 |
| 705 void MessageService::PostMessage(int source_port_id, const Message& message) { | 718 void MessageService::PostMessage(int source_port_id, const Message& message) { |
| 706 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 719 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 707 | 720 |
| 708 int channel_id = GET_CHANNEL_ID(source_port_id); | 721 int channel_id = GET_CHANNEL_ID(source_port_id); |
| 709 MessageChannelMap::iterator iter = channels_.find(channel_id); | 722 MessageChannelMap::iterator iter = channels_.find(channel_id); |
| 710 if (iter == channels_.end()) { | 723 if (iter == channels_.end()) { |
| 711 // If this channel is pending, queue up the PostMessage to run once | 724 // If this channel is pending, queue up the PostMessage to run once |
| 712 // the channel opens. | 725 // the channel opens. |
| 713 EnqueuePendingMessage(source_port_id, channel_id, message); | 726 EnqueuePendingMessage(source_port_id, channel_id, message); |
| 714 return; | 727 return; |
| 715 } | 728 } |
| 716 | 729 |
| 717 DispatchMessage(source_port_id, iter->second, message); | 730 DispatchMessage(source_port_id, iter->second, message); |
| 718 } | 731 } |
| 719 | 732 |
| 720 void MessageService::Observe(int type, | |
| 721 const content::NotificationSource& source, | |
| 722 const content::NotificationDetails& details) { | |
| 723 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 724 | |
| 725 switch (type) { | |
| 726 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: | |
| 727 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { | |
| 728 content::RenderProcessHost* renderer = | |
| 729 content::Source<content::RenderProcessHost>(source).ptr(); | |
| 730 OnProcessClosed(renderer); | |
| 731 break; | |
| 732 } | |
| 733 default: | |
| 734 NOTREACHED(); | |
| 735 return; | |
| 736 } | |
| 737 } | |
| 738 | |
| 739 void MessageService::OnProcessClosed(content::RenderProcessHost* process) { | |
| 740 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 741 | |
| 742 // Close any channels that share this renderer. We notify the opposite | |
| 743 // port that its pair has closed. | |
| 744 for (MessageChannelMap::iterator it = channels_.begin(); | |
| 745 it != channels_.end(); ) { | |
| 746 MessageChannelMap::iterator current = it++; | |
| 747 | |
| 748 content::RenderProcessHost* opener_process = | |
| 749 current->second->opener->GetRenderProcessHost(); | |
| 750 content::RenderProcessHost* receiver_process = | |
| 751 current->second->receiver->GetRenderProcessHost(); | |
| 752 | |
| 753 // Only notify the other side if it has a different porocess host. | |
| 754 bool notify_other_port = opener_process && receiver_process && | |
| 755 opener_process != receiver_process; | |
| 756 | |
| 757 if (opener_process == process) { | |
| 758 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), | |
| 759 std::string(), notify_other_port); | |
| 760 } else if (receiver_process == process) { | |
| 761 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), | |
| 762 std::string(), notify_other_port); | |
| 763 } | |
| 764 } | |
| 765 } | |
| 766 | |
| 767 void MessageService::EnqueuePendingMessage(int source_port_id, | 733 void MessageService::EnqueuePendingMessage(int source_port_id, |
| 768 int channel_id, | 734 int channel_id, |
| 769 const Message& message) { | 735 const Message& message) { |
| 770 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 736 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 771 | 737 |
| 772 PendingChannelMap::iterator pending_for_incognito = | 738 PendingChannelMap::iterator pending_for_incognito = |
| 773 pending_incognito_channels_.find(channel_id); | 739 pending_incognito_channels_.find(channel_id); |
| 774 if (pending_for_incognito != pending_incognito_channels_.end()) { | 740 if (pending_for_incognito != pending_incognito_channels_.end()) { |
| 775 pending_for_incognito->second.push_back( | 741 pending_for_incognito->second.push_back( |
| 776 PendingMessage(source_port_id, message)); | 742 PendingMessage(source_port_id, message)); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 814 void MessageService::DispatchMessage(int source_port_id, | 780 void MessageService::DispatchMessage(int source_port_id, |
| 815 MessageChannel* channel, | 781 MessageChannel* channel, |
| 816 const Message& message) { | 782 const Message& message) { |
| 817 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 783 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 818 | 784 |
| 819 // Figure out which port the ID corresponds to. | 785 // Figure out which port the ID corresponds to. |
| 820 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); | 786 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); |
| 821 MessagePort* port = IS_OPENER_PORT_ID(dest_port_id) ? | 787 MessagePort* port = IS_OPENER_PORT_ID(dest_port_id) ? |
| 822 channel->opener.get() : channel->receiver.get(); | 788 channel->opener.get() : channel->receiver.get(); |
| 823 | 789 |
| 824 port->DispatchOnMessage(message, dest_port_id); | 790 port->DispatchOnMessage(message); |
| 825 } | 791 } |
| 826 | 792 |
| 827 bool MessageService::MaybeAddPendingLazyBackgroundPageOpenChannelTask( | 793 bool MessageService::MaybeAddPendingLazyBackgroundPageOpenChannelTask( |
| 828 BrowserContext* context, | 794 BrowserContext* context, |
| 829 const Extension* extension, | 795 const Extension* extension, |
| 830 scoped_ptr<OpenChannelParams>* params, | 796 scoped_ptr<OpenChannelParams>* params, |
| 831 const PendingMessagesQueue& pending_messages) { | 797 const PendingMessagesQueue& pending_messages) { |
| 832 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 798 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 833 | 799 |
| 834 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) | 800 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 pending_incognito_channels_.find(channel_id); | 835 pending_incognito_channels_.find(channel_id); |
| 870 if (pending_for_incognito == pending_incognito_channels_.end()) { | 836 if (pending_for_incognito == pending_incognito_channels_.end()) { |
| 871 NOTREACHED(); | 837 NOTREACHED(); |
| 872 return; | 838 return; |
| 873 } | 839 } |
| 874 PendingMessagesQueue pending_messages; | 840 PendingMessagesQueue pending_messages; |
| 875 pending_messages.swap(pending_for_incognito->second); | 841 pending_messages.swap(pending_for_incognito->second); |
| 876 pending_incognito_channels_.erase(pending_for_incognito); | 842 pending_incognito_channels_.erase(pending_for_incognito); |
| 877 | 843 |
| 878 // Re-lookup the source process since it may no longer be valid. | 844 // Re-lookup the source process since it may no longer be valid. |
| 879 content::RenderProcessHost* source = | 845 content::RenderFrameHost* source = |
| 880 content::RenderProcessHost::FromID(params->source_process_id); | 846 content::RenderFrameHost::FromID(params->source_process_id, |
| 847 params->source_routing_id); |
| 881 if (!source) { | 848 if (!source) { |
| 882 return; | 849 return; |
| 883 } | 850 } |
| 884 | 851 |
| 885 if (!allowed) { | 852 if (!allowed) { |
| 886 DispatchOnDisconnect(source, params->receiver_port_id, | 853 DispatchOnDisconnect(source, params->receiver_port_id, |
| 887 kReceivingEndDoesntExistError); | 854 kReceivingEndDoesntExistError); |
| 888 return; | 855 return; |
| 889 } | 856 } |
| 890 | 857 |
| 891 BrowserContext* context = source->GetBrowserContext(); | 858 BrowserContext* context = source->GetProcess()->GetBrowserContext(); |
| 892 | 859 |
| 893 // Note: we use the source's profile here. If the source is an incognito | 860 // Note: we use the source's profile here. If the source is an incognito |
| 894 // process, we will use the incognito EPM to find the right extension process, | 861 // process, we will use the incognito EPM to find the right extension process, |
| 895 // which depends on whether the extension uses spanning or split mode. | 862 // which depends on whether the extension uses spanning or split mode. |
| 896 params->receiver.reset(new ExtensionMessagePort( | 863 if (content::RenderProcessHost* extension_process = |
| 897 GetExtensionProcess(context, params->target_extension_id), | 864 GetExtensionProcess(context, params->target_extension_id)) { |
| 898 MSG_ROUTING_CONTROL, params->target_extension_id)); | 865 params->receiver.reset( |
| 866 new ExtensionMessagePort( |
| 867 weak_factory_.GetWeakPtr(), params->receiver_port_id, |
| 868 params->target_extension_id, extension_process)); |
| 869 } else { |
| 870 params->receiver.reset(); |
| 871 } |
| 899 | 872 |
| 900 // If the target requests the TLS channel id, begin the lookup for it. | 873 // If the target requests the TLS channel id, begin the lookup for it. |
| 901 // The target might also be a lazy background page, checked next, but the | 874 // The target might also be a lazy background page, checked next, but the |
| 902 // loading of lazy background pages continues asynchronously, so enqueue | 875 // loading of lazy background pages continues asynchronously, so enqueue |
| 903 // messages awaiting TLS channel ID first. | 876 // messages awaiting TLS channel ID first. |
| 904 if (params->include_tls_channel_id) { | 877 if (params->include_tls_channel_id) { |
| 905 // Transfer pending messages to the next pending channel list. | 878 // Transfer pending messages to the next pending channel list. |
| 906 pending_tls_channel_id_channels_[channel_id].swap(pending_messages); | 879 pending_tls_channel_id_channels_[channel_id].swap(pending_messages); |
| 907 // Capture this reference before params is invalidated by base::Passed(). | 880 // Capture this reference before params is invalidated by base::Passed(). |
| 908 const GURL& source_url = params->source_url; | 881 const GURL& source_url = params->source_url; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 pending_tls_channel_id_channels_.find(channel_id); | 917 pending_tls_channel_id_channels_.find(channel_id); |
| 945 if (pending_for_tls_channel_id == pending_tls_channel_id_channels_.end()) { | 918 if (pending_for_tls_channel_id == pending_tls_channel_id_channels_.end()) { |
| 946 NOTREACHED(); | 919 NOTREACHED(); |
| 947 return; | 920 return; |
| 948 } | 921 } |
| 949 PendingMessagesQueue pending_messages; | 922 PendingMessagesQueue pending_messages; |
| 950 pending_messages.swap(pending_for_tls_channel_id->second); | 923 pending_messages.swap(pending_for_tls_channel_id->second); |
| 951 pending_tls_channel_id_channels_.erase(pending_for_tls_channel_id); | 924 pending_tls_channel_id_channels_.erase(pending_for_tls_channel_id); |
| 952 | 925 |
| 953 // Re-lookup the source process since it may no longer be valid. | 926 // Re-lookup the source process since it may no longer be valid. |
| 954 content::RenderProcessHost* source = | 927 content::RenderFrameHost* source = |
| 955 content::RenderProcessHost::FromID(params->source_process_id); | 928 content::RenderFrameHost::FromID(params->source_process_id, |
| 929 params->source_routing_id); |
| 956 if (!source) { | 930 if (!source) { |
| 957 return; | 931 return; |
| 958 } | 932 } |
| 959 | 933 |
| 960 BrowserContext* context = source->GetBrowserContext(); | 934 BrowserContext* context = source->GetProcess()->GetBrowserContext(); |
| 961 ExtensionRegistry* registry = ExtensionRegistry::Get(context); | 935 ExtensionRegistry* registry = ExtensionRegistry::Get(context); |
| 962 const Extension* target_extension = | 936 const Extension* target_extension = |
| 963 registry->enabled_extensions().GetByID(params->target_extension_id); | 937 registry->enabled_extensions().GetByID(params->target_extension_id); |
| 964 if (!target_extension) { | 938 if (!target_extension) { |
| 965 DispatchOnDisconnect(source, params->receiver_port_id, | 939 DispatchOnDisconnect(source, params->receiver_port_id, |
| 966 kReceivingEndDoesntExistError); | 940 kReceivingEndDoesntExistError); |
| 967 return; | 941 return; |
| 968 } | 942 } |
| 969 | 943 |
| 970 if (!MaybeAddPendingLazyBackgroundPageOpenChannelTask( | 944 if (!MaybeAddPendingLazyBackgroundPageOpenChannelTask( |
| 971 context, target_extension, ¶ms, pending_messages)) { | 945 context, target_extension, ¶ms, pending_messages)) { |
| 972 OpenChannelImpl(context, params.Pass(), target_extension, | 946 OpenChannelImpl(context, params.Pass(), target_extension, |
| 973 false /* did_enqueue */); | 947 false /* did_enqueue */); |
| 974 DispatchPendingMessages(pending_messages, channel_id); | 948 DispatchPendingMessages(pending_messages, channel_id); |
| 975 } | 949 } |
| 976 } | 950 } |
| 977 | 951 |
| 978 void MessageService::PendingLazyBackgroundPageOpenChannel( | 952 void MessageService::PendingLazyBackgroundPageOpenChannel( |
| 979 scoped_ptr<OpenChannelParams> params, | 953 scoped_ptr<OpenChannelParams> params, |
| 980 int source_process_id, | 954 int source_process_id, |
| 981 ExtensionHost* host) { | 955 ExtensionHost* host) { |
| 982 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 956 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 983 | 957 |
| 984 if (!host) | 958 if (!host) |
| 985 return; // TODO(mpcomplete): notify source of disconnect? | 959 return; // TODO(mpcomplete): notify source of disconnect? |
| 986 | 960 |
| 987 params->receiver.reset(new ExtensionMessagePort(host->render_process_host(), | 961 params->receiver.reset( |
| 988 MSG_ROUTING_CONTROL, | 962 new ExtensionMessagePort( |
| 989 params->target_extension_id)); | 963 weak_factory_.GetWeakPtr(), params->receiver_port_id, |
| 964 params->target_extension_id, host->render_process_host())); |
| 990 OpenChannelImpl(host->browser_context(), params.Pass(), host->extension(), | 965 OpenChannelImpl(host->browser_context(), params.Pass(), host->extension(), |
| 991 true /* did_enqueue */); | 966 true /* did_enqueue */); |
| 992 } | 967 } |
| 993 | 968 |
| 994 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source, | 969 void MessageService::DispatchOnDisconnect(content::RenderFrameHost* source, |
| 995 int port_id, | 970 int port_id, |
| 996 const std::string& error_message) { | 971 const std::string& error_message) { |
| 997 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 972 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 998 | 973 |
| 999 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, ""); | 974 ExtensionMessagePort port(weak_factory_.GetWeakPtr(), |
| 1000 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message); | 975 GET_OPPOSITE_PORT_ID(port_id), "", source, false); |
| 976 port.DispatchOnDisconnect(error_message); |
| 1001 } | 977 } |
| 1002 | 978 |
| 1003 void MessageService::DispatchPendingMessages(const PendingMessagesQueue& queue, | 979 void MessageService::DispatchPendingMessages(const PendingMessagesQueue& queue, |
| 1004 int channel_id) { | 980 int channel_id) { |
| 1005 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 981 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1006 | 982 |
| 1007 MessageChannelMap::iterator channel_iter = channels_.find(channel_id); | 983 MessageChannelMap::iterator channel_iter = channels_.find(channel_id); |
| 1008 if (channel_iter != channels_.end()) { | 984 if (channel_iter != channels_.end()) { |
| 1009 for (const PendingMessage& message : queue) { | 985 for (const PendingMessage& message : queue) { |
| 1010 DispatchMessage(message.first, channel_iter->second, message.second); | 986 DispatchMessage(message.first, channel_iter->second, message.second); |
| 1011 } | 987 } |
| 1012 } | 988 } |
| 1013 } | 989 } |
| 1014 | 990 |
| 1015 } // namespace extensions | 991 } // namespace extensions |
| OLD | NEW |