OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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 // Represents the browser side of the browser <--> renderer communication | 5 // Represents the browser side of the browser <--> renderer communication |
6 // channel. There will be one RenderProcessHost per renderer process. | 6 // channel. There will be one RenderProcessHost per renderer process. |
7 | 7 |
8 #include "content/browser/renderer_host/render_process_host_impl.h" | 8 #include "content/browser/renderer_host/render_process_host_impl.h" |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 #include "gpu/command_buffer/service/gpu_switches.h" | 168 #include "gpu/command_buffer/service/gpu_switches.h" |
169 #include "ipc/attachment_broker.h" | 169 #include "ipc/attachment_broker.h" |
170 #include "ipc/attachment_broker_privileged.h" | 170 #include "ipc/attachment_broker_privileged.h" |
171 #include "ipc/ipc.mojom.h" | 171 #include "ipc/ipc.mojom.h" |
172 #include "ipc/ipc_channel.h" | 172 #include "ipc/ipc_channel.h" |
173 #include "ipc/ipc_channel_mojo.h" | 173 #include "ipc/ipc_channel_mojo.h" |
174 #include "ipc/ipc_logging.h" | 174 #include "ipc/ipc_logging.h" |
175 #include "ipc/ipc_switches.h" | 175 #include "ipc/ipc_switches.h" |
176 #include "media/base/media_switches.h" | 176 #include "media/base/media_switches.h" |
177 #include "mojo/edk/embedder/embedder.h" | 177 #include "mojo/edk/embedder/embedder.h" |
| 178 #include "mojo/public/cpp/bindings/associated_interface_ptr.h" |
178 #include "net/url_request/url_request_context_getter.h" | 179 #include "net/url_request/url_request_context_getter.h" |
179 #include "ppapi/shared_impl/ppapi_switches.h" | 180 #include "ppapi/shared_impl/ppapi_switches.h" |
180 #include "services/shell/public/cpp/connection.h" | 181 #include "services/shell/public/cpp/connection.h" |
181 #include "services/shell/public/cpp/interface_provider.h" | 182 #include "services/shell/public/cpp/interface_provider.h" |
182 #include "services/shell/public/cpp/interface_registry.h" | 183 #include "services/shell/public/cpp/interface_registry.h" |
183 #include "services/shell/runner/common/switches.h" | 184 #include "services/shell/runner/common/switches.h" |
184 #include "storage/browser/fileapi/sandbox_file_system_backend.h" | 185 #include "storage/browser/fileapi/sandbox_file_system_backend.h" |
185 #include "third_party/skia/include/core/SkBitmap.h" | 186 #include "third_party/skia/include/core/SkBitmap.h" |
186 #include "ui/base/ui_base_switches.h" | 187 #include "ui/base/ui_base_switches.h" |
187 #include "ui/display/display_switches.h" | 188 #include "ui/display/display_switches.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 | 243 |
243 #if defined(OS_WIN) | 244 #if defined(OS_WIN) |
244 #define IntToStringType base::IntToString16 | 245 #define IntToStringType base::IntToString16 |
245 #else | 246 #else |
246 #define IntToStringType base::IntToString | 247 #define IntToStringType base::IntToString |
247 #endif | 248 #endif |
248 | 249 |
249 namespace content { | 250 namespace content { |
250 namespace { | 251 namespace { |
251 | 252 |
| 253 const char kRendererInterfaceKeyName[] = "mojom_renderer_interface"; |
252 const char kSiteProcessMapKeyName[] = "content_site_process_map"; | 254 const char kSiteProcessMapKeyName[] = "content_site_process_map"; |
253 | 255 |
254 #ifdef ENABLE_WEBRTC | 256 #ifdef ENABLE_WEBRTC |
255 const base::FilePath::CharType kAecDumpFileNameAddition[] = | 257 const base::FilePath::CharType kAecDumpFileNameAddition[] = |
256 FILE_PATH_LITERAL("aec_dump"); | 258 FILE_PATH_LITERAL("aec_dump"); |
257 #endif | 259 #endif |
258 | 260 |
259 void CacheShaderInfo(int32_t id, base::FilePath path) { | 261 void CacheShaderInfo(int32_t id, base::FilePath path) { |
260 ShaderCacheFactory::GetInstance()->SetCacheInfo(id, path); | 262 ShaderCacheFactory::GetInstance()->SetCacheInfo(id, path); |
261 } | 263 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 DCHECK(context); | 360 DCHECK(context); |
359 SiteProcessMap* map = static_cast<SiteProcessMap*>( | 361 SiteProcessMap* map = static_cast<SiteProcessMap*>( |
360 context->GetUserData(kSiteProcessMapKeyName)); | 362 context->GetUserData(kSiteProcessMapKeyName)); |
361 if (!map) { | 363 if (!map) { |
362 map = new SiteProcessMap(); | 364 map = new SiteProcessMap(); |
363 context->SetUserData(kSiteProcessMapKeyName, map); | 365 context->SetUserData(kSiteProcessMapKeyName, map); |
364 } | 366 } |
365 return map; | 367 return map; |
366 } | 368 } |
367 | 369 |
| 370 // Holds a Mojo associated interface proxy in an RPH's user data. |
| 371 template <typename Interface> |
| 372 class AssociatedInterfaceHolder : public base::SupportsUserData::Data { |
| 373 public: |
| 374 AssociatedInterfaceHolder() {} |
| 375 ~AssociatedInterfaceHolder() override {} |
| 376 |
| 377 mojo::AssociatedInterfacePtr<Interface>& proxy() { return proxy_; } |
| 378 |
| 379 private: |
| 380 mojo::AssociatedInterfacePtr<Interface> proxy_; |
| 381 |
| 382 DISALLOW_COPY_AND_ASSIGN(AssociatedInterfaceHolder); |
| 383 }; |
| 384 |
368 #if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX) | 385 #if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX) |
369 // This static member variable holds the zygote communication information for | 386 // This static member variable holds the zygote communication information for |
370 // the renderer. | 387 // the renderer. |
371 ZygoteHandle g_render_zygote; | 388 ZygoteHandle g_render_zygote; |
372 #endif // defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX) | 389 #endif // defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX) |
373 | 390 |
374 // NOTE: changes to this class need to be reviewed by the security team. | 391 // NOTE: changes to this class need to be reviewed by the security team. |
375 class RendererSandboxedProcessLauncherDelegate | 392 class RendererSandboxedProcessLauncherDelegate |
376 : public SandboxedProcessLauncherDelegate { | 393 : public SandboxedProcessLauncherDelegate { |
377 public: | 394 public: |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 void RenderProcessHostImpl::EnableSendQueue() { | 845 void RenderProcessHostImpl::EnableSendQueue() { |
829 is_initialized_ = false; | 846 is_initialized_ = false; |
830 } | 847 } |
831 | 848 |
832 bool RenderProcessHostImpl::Init() { | 849 bool RenderProcessHostImpl::Init() { |
833 // calling Init() more than once does nothing, this makes it more convenient | 850 // calling Init() more than once does nothing, this makes it more convenient |
834 // for the view host which may not be sure in some cases | 851 // for the view host which may not be sure in some cases |
835 if (channel_) | 852 if (channel_) |
836 return true; | 853 return true; |
837 | 854 |
838 // Ensure that the remote associated interfaces are re-initialized on next | |
839 // access since they're associated with a specific Channel instance. | |
840 remote_route_provider_.reset(); | |
841 renderer_interface_.reset(); | |
842 | |
843 base::CommandLine::StringType renderer_prefix; | 855 base::CommandLine::StringType renderer_prefix; |
844 // A command prefix is something prepended to the command line of the spawned | 856 // A command prefix is something prepended to the command line of the spawned |
845 // process. | 857 // process. |
846 const base::CommandLine& browser_command_line = | 858 const base::CommandLine& browser_command_line = |
847 *base::CommandLine::ForCurrentProcess(); | 859 *base::CommandLine::ForCurrentProcess(); |
848 renderer_prefix = | 860 renderer_prefix = |
849 browser_command_line.GetSwitchValueNative(switches::kRendererCmdPrefix); | 861 browser_command_line.GetSwitchValueNative(switches::kRendererCmdPrefix); |
850 | 862 |
851 #if defined(OS_LINUX) | 863 #if defined(OS_LINUX) |
852 int flags = renderer_prefix.empty() ? ChildProcessHost::CHILD_ALLOW_SELF | 864 int flags = renderer_prefix.empty() ? ChildProcessHost::CHILD_ALLOW_SELF |
853 : ChildProcessHost::CHILD_NORMAL; | 865 : ChildProcessHost::CHILD_NORMAL; |
854 #else | 866 #else |
855 int flags = ChildProcessHost::CHILD_NORMAL; | 867 int flags = ChildProcessHost::CHILD_NORMAL; |
856 #endif | 868 #endif |
857 | 869 |
858 // Find the renderer before creating the channel so if this fails early we | 870 // Find the renderer before creating the channel so if this fails early we |
859 // return without creating the channel. | 871 // return without creating the channel. |
860 base::FilePath renderer_path = ChildProcessHost::GetChildPath(flags); | 872 base::FilePath renderer_path = ChildProcessHost::GetChildPath(flags); |
861 if (renderer_path.empty()) | 873 if (renderer_path.empty()) |
862 return false; | 874 return false; |
863 | 875 |
864 channel_connected_ = false; | 876 channel_connected_ = false; |
865 sent_render_process_ready_ = false; | 877 sent_render_process_ready_ = false; |
866 | 878 |
867 // Setup the IPC channel. | 879 // Setup the IPC channel. |
868 const std::string channel_id = | 880 const std::string channel_id = |
869 IPC::Channel::GenerateVerifiedChannelID(std::string()); | 881 IPC::Channel::GenerateVerifiedChannelID(std::string()); |
870 channel_ = CreateChannelProxy(channel_id); | 882 channel_ = CreateChannelProxy(channel_id); |
871 | 883 |
| 884 // Note that Channel send is effectively paused and unpaused at various points |
| 885 // during startup, and existing code relies on a fragile relative message |
| 886 // ordering resulting from some early messages being queued until process |
| 887 // launch while others are sent immediately. |
| 888 // |
| 889 // We acquire a few associated interface proxies here -- before the channel is |
| 890 // paused -- to ensure that subsequent initialization messages on those |
| 891 // interfaces behave properly. Specifically, this avoids the risk of an |
| 892 // interface being requested while the Channel is paused, effectively |
| 893 // blocking the transmission of a subsequent message on the interface which |
| 894 // may be sent while the Channel is unpaused. |
| 895 // |
| 896 // See OnProcessLaunched() for some additional details of this somewhat |
| 897 // surprising behavior. |
| 898 channel_->GetRemoteAssociatedInterface(&remote_route_provider_); |
| 899 |
| 900 std::unique_ptr<AssociatedInterfaceHolder<mojom::Renderer>> holder = |
| 901 base::MakeUnique<AssociatedInterfaceHolder<mojom::Renderer>>(); |
| 902 channel_->GetRemoteAssociatedInterface(&holder->proxy()); |
| 903 SetUserData(kRendererInterfaceKeyName, holder.release()); |
| 904 |
872 // Call the embedder first so that their IPC filters have priority. | 905 // Call the embedder first so that their IPC filters have priority. |
873 GetContentClient()->browser()->RenderProcessWillLaunch(this); | 906 GetContentClient()->browser()->RenderProcessWillLaunch(this); |
874 | 907 |
875 #if !defined(OS_MACOSX) | 908 #if !defined(OS_MACOSX) |
876 // Intentionally delay the hang monitor creation after the first renderer | 909 // Intentionally delay the hang monitor creation after the first renderer |
877 // is created. On Mac audio thread is the UI thread, a hang monitor is not | 910 // is created. On Mac audio thread is the UI thread, a hang monitor is not |
878 // necessary or recommended. | 911 // necessary or recommended. |
879 media::AudioManager::StartHangMonitorIfNeeded( | 912 media::AudioManager::StartHangMonitorIfNeeded( |
880 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); | 913 BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); |
881 #endif // !defined(OS_MACOSX) | 914 #endif // !defined(OS_MACOSX) |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1380 bool RenderProcessHostImpl::IsWorkerRefCountDisabled() { | 1413 bool RenderProcessHostImpl::IsWorkerRefCountDisabled() { |
1381 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1414 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
1382 return is_worker_ref_count_disabled_; | 1415 return is_worker_ref_count_disabled_; |
1383 } | 1416 } |
1384 | 1417 |
1385 void RenderProcessHostImpl::PurgeAndSuspend() { | 1418 void RenderProcessHostImpl::PurgeAndSuspend() { |
1386 Send(new ChildProcessMsg_PurgeAndSuspend()); | 1419 Send(new ChildProcessMsg_PurgeAndSuspend()); |
1387 } | 1420 } |
1388 | 1421 |
1389 mojom::RouteProvider* RenderProcessHostImpl::GetRemoteRouteProvider() { | 1422 mojom::RouteProvider* RenderProcessHostImpl::GetRemoteRouteProvider() { |
1390 if (!remote_route_provider_) { | |
1391 DCHECK(channel_); | |
1392 channel_->GetRemoteAssociatedInterface(&remote_route_provider_); | |
1393 } | |
1394 return remote_route_provider_.get(); | 1423 return remote_route_provider_.get(); |
1395 } | 1424 } |
1396 | 1425 |
1397 mojom::Renderer* RenderProcessHostImpl::GetRendererInterface() { | 1426 // static |
1398 if (!renderer_interface_) { | 1427 mojom::Renderer* RenderProcessHostImpl::GetRendererInterface( |
1399 DCHECK(channel_); | 1428 RenderProcessHost* host) { |
1400 channel_->GetRemoteAssociatedInterface(&renderer_interface_); | 1429 AssociatedInterfaceHolder<mojom::Renderer>* holder = |
| 1430 static_cast<AssociatedInterfaceHolder<mojom::Renderer>*>( |
| 1431 host->GetUserData(kRendererInterfaceKeyName)); |
| 1432 if (!holder) { |
| 1433 // In tests, MockRenderProcessHost will not have initialized this key on its |
| 1434 // own. We do it with a dead-end endpoint so outgoing requests are silently |
| 1435 // dropped. |
| 1436 holder = new AssociatedInterfaceHolder<mojom::Renderer>; |
| 1437 host->SetUserData(kRendererInterfaceKeyName, holder); |
| 1438 mojo::GetDummyProxyForTesting(&holder->proxy()); |
1401 } | 1439 } |
1402 return renderer_interface_.get(); | 1440 |
| 1441 return holder->proxy().get(); |
1403 } | 1442 } |
1404 | 1443 |
1405 void RenderProcessHostImpl::AddRoute(int32_t routing_id, | 1444 void RenderProcessHostImpl::AddRoute(int32_t routing_id, |
1406 IPC::Listener* listener) { | 1445 IPC::Listener* listener) { |
1407 CHECK(!listeners_.Lookup(routing_id)) << "Found Routing ID Conflict: " | 1446 CHECK(!listeners_.Lookup(routing_id)) << "Found Routing ID Conflict: " |
1408 << routing_id; | 1447 << routing_id; |
1409 listeners_.AddWithID(listener, routing_id); | 1448 listeners_.AddWithID(listener, routing_id); |
1410 } | 1449 } |
1411 | 1450 |
1412 void RenderProcessHostImpl::RemoveRoute(int32_t routing_id) { | 1451 void RenderProcessHostImpl::RemoveRoute(int32_t routing_id) { |
(...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2646 RendererClosedDetails details(status, exit_code); | 2685 RendererClosedDetails details(status, exit_code); |
2647 | 2686 |
2648 child_process_launcher_.reset(); | 2687 child_process_launcher_.reset(); |
2649 #if USE_ATTACHMENT_BROKER | 2688 #if USE_ATTACHMENT_BROKER |
2650 IPC::AttachmentBroker::GetGlobal()->DeregisterCommunicationChannel( | 2689 IPC::AttachmentBroker::GetGlobal()->DeregisterCommunicationChannel( |
2651 channel_.get()); | 2690 channel_.get()); |
2652 #endif | 2691 #endif |
2653 channel_.reset(); | 2692 channel_.reset(); |
2654 queued_messages_ = MessageQueue{}; | 2693 queued_messages_ = MessageQueue{}; |
2655 | 2694 |
| 2695 // Clear all cached associated interface proxies as well, since these are |
| 2696 // effectively bound to the lifetime of the Channel. |
| 2697 remote_route_provider_.reset(); |
| 2698 RemoveUserData(kRendererInterfaceKeyName); |
| 2699 |
2656 UpdateProcessPriority(); | 2700 UpdateProcessPriority(); |
2657 DCHECK(!is_process_backgrounded_); | 2701 DCHECK(!is_process_backgrounded_); |
2658 | 2702 |
2659 // RenderProcessExited observers and RenderProcessGone handlers might | 2703 // RenderProcessExited observers and RenderProcessGone handlers might |
2660 // navigate or perform other actions that require a connection. Ensure that | 2704 // navigate or perform other actions that require a connection. Ensure that |
2661 // there is one before calling them. | 2705 // there is one before calling them. |
2662 child_token_ = mojo::edk::GenerateRandomToken(); | 2706 child_token_ = mojo::edk::GenerateRandomToken(); |
2663 shell::Connector* connector = | 2707 shell::Connector* connector = |
2664 BrowserContext::GetShellConnectorFor(browser_context_); | 2708 BrowserContext::GetShellConnectorFor(browser_context_); |
2665 if (!connector) | 2709 if (!connector) |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3002 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; | 3046 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; |
3003 | 3047 |
3004 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. Alias | 3048 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. Alias |
3005 // enough information here so that we can determine what the bad message was. | 3049 // enough information here so that we can determine what the bad message was. |
3006 base::debug::Alias(&error); | 3050 base::debug::Alias(&error); |
3007 bad_message::ReceivedBadMessage(process.get(), | 3051 bad_message::ReceivedBadMessage(process.get(), |
3008 bad_message::RPH_MOJO_PROCESS_ERROR); | 3052 bad_message::RPH_MOJO_PROCESS_ERROR); |
3009 } | 3053 } |
3010 | 3054 |
3011 } // namespace content | 3055 } // namespace content |
OLD | NEW |