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 // 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 #include "content/common/child_process_messages.h" | 98 #include "content/common/child_process_messages.h" |
99 #include "content/common/gpu/gpu_messages.h" | 99 #include "content/common/gpu/gpu_messages.h" |
100 #include "content/common/resource_messages.h" | 100 #include "content/common/resource_messages.h" |
101 #include "content/common/view_messages.h" | 101 #include "content/common/view_messages.h" |
102 #include "content/port/browser/render_widget_host_view_frame_subscriber.h" | 102 #include "content/port/browser/render_widget_host_view_frame_subscriber.h" |
103 #include "content/public/browser/browser_context.h" | 103 #include "content/public/browser/browser_context.h" |
104 #include "content/public/browser/content_browser_client.h" | 104 #include "content/public/browser/content_browser_client.h" |
105 #include "content/public/browser/notification_service.h" | 105 #include "content/public/browser/notification_service.h" |
106 #include "content/public/browser/notification_types.h" | 106 #include "content/public/browser/notification_types.h" |
107 #include "content/public/browser/render_process_host_factory.h" | 107 #include "content/public/browser/render_process_host_factory.h" |
| 108 #include "content/public/browser/render_widget_host.h" |
108 #include "content/public/browser/resource_context.h" | 109 #include "content/public/browser/resource_context.h" |
109 #include "content/public/browser/user_metrics.h" | 110 #include "content/public/browser/user_metrics.h" |
110 #include "content/public/common/content_constants.h" | 111 #include "content/public/common/content_constants.h" |
111 #include "content/public/common/content_switches.h" | 112 #include "content/public/common/content_switches.h" |
112 #include "content/public/common/process_type.h" | 113 #include "content/public/common/process_type.h" |
113 #include "content/public/common/result_codes.h" | 114 #include "content/public/common/result_codes.h" |
114 #include "content/public/common/url_constants.h" | 115 #include "content/public/common/url_constants.h" |
115 #include "content/renderer/render_process_impl.h" | 116 #include "content/renderer/render_process_impl.h" |
116 #include "content/renderer/render_thread_impl.h" | 117 #include "content/renderer/render_thread_impl.h" |
117 #include "gpu/command_buffer/service/gpu_switches.h" | 118 #include "gpu/command_buffer/service/gpu_switches.h" |
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 if (CommandLine::ForCurrentProcess()->HasSwitch( | 699 if (CommandLine::ForCurrentProcess()->HasSwitch( |
699 switches::kEnableMemoryBenchmarking)) | 700 switches::kEnableMemoryBenchmarking)) |
700 channel_->AddFilter(new MemoryBenchmarkMessageFilter()); | 701 channel_->AddFilter(new MemoryBenchmarkMessageFilter()); |
701 #endif | 702 #endif |
702 } | 703 } |
703 | 704 |
704 int RenderProcessHostImpl::GetNextRoutingID() { | 705 int RenderProcessHostImpl::GetNextRoutingID() { |
705 return widget_helper_->GetNextRoutingID(); | 706 return widget_helper_->GetNextRoutingID(); |
706 } | 707 } |
707 | 708 |
| 709 |
708 void RenderProcessHostImpl::ResumeDeferredNavigation( | 710 void RenderProcessHostImpl::ResumeDeferredNavigation( |
709 const GlobalRequestID& request_id) { | 711 const GlobalRequestID& request_id) { |
710 widget_helper_->ResumeDeferredNavigation(request_id); | 712 widget_helper_->ResumeDeferredNavigation(request_id); |
711 } | 713 } |
712 | 714 |
| 715 void RenderProcessHostImpl::AddRoute( |
| 716 int32 routing_id, |
| 717 IPC::Listener* listener) { |
| 718 listeners_.AddWithID(listener, routing_id); |
| 719 } |
| 720 |
| 721 void RenderProcessHostImpl::RemoveRoute(int32 routing_id) { |
| 722 DCHECK(listeners_.Lookup(routing_id) != NULL); |
| 723 listeners_.Remove(routing_id); |
| 724 |
| 725 #if defined(OS_WIN) |
| 726 // Dump the handle table if handle auditing is enabled. |
| 727 const CommandLine& browser_command_line = |
| 728 *CommandLine::ForCurrentProcess(); |
| 729 if (browser_command_line.HasSwitch(switches::kAuditHandles) || |
| 730 browser_command_line.HasSwitch(switches::kAuditAllHandles)) { |
| 731 DumpHandles(); |
| 732 |
| 733 // We wait to close the channels until the child process has finished |
| 734 // dumping handles and sends us ChildProcessHostMsg_DumpHandlesDone. |
| 735 return; |
| 736 } |
| 737 #endif |
| 738 // Keep the one renderer thread around forever in single process mode. |
| 739 if (!run_renderer_in_process()) |
| 740 Cleanup(); |
| 741 } |
| 742 |
713 bool RenderProcessHostImpl::WaitForBackingStoreMsg( | 743 bool RenderProcessHostImpl::WaitForBackingStoreMsg( |
714 int render_widget_id, | 744 int render_widget_id, |
715 const base::TimeDelta& max_delay, | 745 const base::TimeDelta& max_delay, |
716 IPC::Message* msg) { | 746 IPC::Message* msg) { |
717 // The post task to this thread with the process id could be in queue, and we | 747 // The post task to this thread with the process id could be in queue, and we |
718 // don't want to dispatch a message before then since it will need the handle. | 748 // don't want to dispatch a message before then since it will need the handle. |
719 if (child_process_launcher_.get() && child_process_launcher_->IsStarting()) | 749 if (child_process_launcher_.get() && child_process_launcher_->IsStarting()) |
720 return false; | 750 return false; |
721 | 751 |
722 return widget_helper_->WaitForBackingStoreMsg(render_widget_id, | 752 return widget_helper_->WaitForBackingStoreMsg(render_widget_id, |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 if (!msg_is_ok) { | 1207 if (!msg_is_ok) { |
1178 // The message had a handler, but its de-serialization failed. | 1208 // The message had a handler, but its de-serialization failed. |
1179 // We consider this a capital crime. Kill the renderer if we have one. | 1209 // We consider this a capital crime. Kill the renderer if we have one. |
1180 LOG(ERROR) << "bad message " << msg.type() << " terminating renderer."; | 1210 LOG(ERROR) << "bad message " << msg.type() << " terminating renderer."; |
1181 RecordAction(UserMetricsAction("BadMessageTerminate_BRPH")); | 1211 RecordAction(UserMetricsAction("BadMessageTerminate_BRPH")); |
1182 ReceivedBadMessage(); | 1212 ReceivedBadMessage(); |
1183 } | 1213 } |
1184 return true; | 1214 return true; |
1185 } | 1215 } |
1186 | 1216 |
1187 // Dispatch incoming messages to the appropriate RenderView/WidgetHost. | 1217 // Dispatch incoming messages to the appropriate IPC::Listener. |
1188 RenderWidgetHost* rwh = render_widget_hosts_.Lookup(msg.routing_id()); | 1218 IPC::Listener* listener = listeners_.Lookup(msg.routing_id()); |
1189 if (!rwh) { | 1219 if (!listener) { |
1190 if (msg.is_sync()) { | 1220 if (msg.is_sync()) { |
1191 // The listener has gone away, so we must respond or else the caller will | 1221 // The listener has gone away, so we must respond or else the caller will |
1192 // hang waiting for a reply. | 1222 // hang waiting for a reply. |
1193 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg); | 1223 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg); |
1194 reply->set_reply_error(); | 1224 reply->set_reply_error(); |
1195 Send(reply); | 1225 Send(reply); |
1196 } | 1226 } |
1197 | 1227 |
1198 // If this is a SwapBuffers, we need to ack it if we're not going to handle | 1228 // If this is a SwapBuffers, we need to ack it if we're not going to handle |
1199 // it so that the GPU process doesn't get stuck in unscheduled state. | 1229 // it so that the GPU process doesn't get stuck in unscheduled state. |
1200 bool msg_is_ok = true; | 1230 bool msg_is_ok = true; |
1201 IPC_BEGIN_MESSAGE_MAP_EX(RenderProcessHostImpl, msg, msg_is_ok) | 1231 IPC_BEGIN_MESSAGE_MAP_EX(RenderProcessHostImpl, msg, msg_is_ok) |
1202 IPC_MESSAGE_HANDLER(ViewHostMsg_CompositorSurfaceBuffersSwapped, | 1232 IPC_MESSAGE_HANDLER(ViewHostMsg_CompositorSurfaceBuffersSwapped, |
1203 OnCompositorSurfaceBuffersSwappedNoHost) | 1233 OnCompositorSurfaceBuffersSwappedNoHost) |
1204 IPC_END_MESSAGE_MAP_EX() | 1234 IPC_END_MESSAGE_MAP_EX() |
1205 return true; | 1235 return true; |
1206 } | 1236 } |
1207 return RenderWidgetHostImpl::From(rwh)->OnMessageReceived(msg); | 1237 return listener->OnMessageReceived(msg); |
1208 } | 1238 } |
1209 | 1239 |
1210 void RenderProcessHostImpl::OnChannelConnected(int32 peer_pid) { | 1240 void RenderProcessHostImpl::OnChannelConnected(int32 peer_pid) { |
1211 #if defined(IPC_MESSAGE_LOG_ENABLED) | 1241 #if defined(IPC_MESSAGE_LOG_ENABLED) |
1212 Send(new ChildProcessMsg_SetIPCLoggingEnabled( | 1242 Send(new ChildProcessMsg_SetIPCLoggingEnabled( |
1213 IPC::Logging::GetInstance()->Enabled())); | 1243 IPC::Logging::GetInstance()->Enabled())); |
1214 #endif | 1244 #endif |
1215 | 1245 |
1216 tracked_objects::ThreadData::Status status = | 1246 tracked_objects::ThreadData::Status status = |
1217 tracked_objects::ThreadData::status(); | 1247 tracked_objects::ThreadData::status(); |
(...skipping 14 matching lines...) Expand all Loading... |
1232 } | 1262 } |
1233 | 1263 |
1234 int RenderProcessHostImpl::GetID() const { | 1264 int RenderProcessHostImpl::GetID() const { |
1235 return id_; | 1265 return id_; |
1236 } | 1266 } |
1237 | 1267 |
1238 bool RenderProcessHostImpl::HasConnection() const { | 1268 bool RenderProcessHostImpl::HasConnection() const { |
1239 return channel_.get() != NULL; | 1269 return channel_.get() != NULL; |
1240 } | 1270 } |
1241 | 1271 |
1242 RenderWidgetHost* RenderProcessHostImpl::GetRenderWidgetHostByID( | |
1243 int routing_id) { | |
1244 return render_widget_hosts_.Lookup(routing_id); | |
1245 } | |
1246 | |
1247 void RenderProcessHostImpl::SetIgnoreInputEvents(bool ignore_input_events) { | 1272 void RenderProcessHostImpl::SetIgnoreInputEvents(bool ignore_input_events) { |
1248 ignore_input_events_ = ignore_input_events; | 1273 ignore_input_events_ = ignore_input_events; |
1249 } | 1274 } |
1250 | 1275 |
1251 bool RenderProcessHostImpl::IgnoreInputEvents() const { | 1276 bool RenderProcessHostImpl::IgnoreInputEvents() const { |
1252 return ignore_input_events_; | 1277 return ignore_input_events_; |
1253 } | 1278 } |
1254 | 1279 |
1255 void RenderProcessHostImpl::Attach(RenderWidgetHost* host, | |
1256 int routing_id) { | |
1257 render_widget_hosts_.AddWithID(host, routing_id); | |
1258 } | |
1259 | |
1260 void RenderProcessHostImpl::Release(int routing_id) { | |
1261 DCHECK(render_widget_hosts_.Lookup(routing_id) != NULL); | |
1262 render_widget_hosts_.Remove(routing_id); | |
1263 | |
1264 #if defined(OS_WIN) | |
1265 // Dump the handle table if handle auditing is enabled. | |
1266 const CommandLine& browser_command_line = | |
1267 *CommandLine::ForCurrentProcess(); | |
1268 if (browser_command_line.HasSwitch(switches::kAuditHandles) || | |
1269 browser_command_line.HasSwitch(switches::kAuditAllHandles)) { | |
1270 DumpHandles(); | |
1271 | |
1272 // We wait to close the channels until the child process has finished | |
1273 // dumping handles and sends us ChildProcessHostMsg_DumpHandlesDone. | |
1274 return; | |
1275 } | |
1276 #endif | |
1277 // Keep the one renderer thread around forever in single process mode. | |
1278 if (!run_renderer_in_process()) | |
1279 Cleanup(); | |
1280 } | |
1281 | |
1282 void RenderProcessHostImpl::Cleanup() { | 1280 void RenderProcessHostImpl::Cleanup() { |
1283 // When no other owners of this object, we can delete ourselves | 1281 // When no other owners of this object, we can delete ourselves |
1284 if (render_widget_hosts_.IsEmpty()) { | 1282 if (listeners_.IsEmpty()) { |
1285 DCHECK_EQ(0, pending_views_); | 1283 DCHECK_EQ(0, pending_views_); |
1286 NotificationService::current()->Notify( | 1284 NotificationService::current()->Notify( |
1287 NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 1285 NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
1288 Source<RenderProcessHost>(this), | 1286 Source<RenderProcessHost>(this), |
1289 NotificationService::NoDetails()); | 1287 NotificationService::NoDetails()); |
1290 | 1288 |
1291 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 1289 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
1292 deleting_soon_ = true; | 1290 deleting_soon_ = true; |
1293 // It's important not to wait for the DeleteTask to delete the channel | 1291 // It's important not to wait for the DeleteTask to delete the channel |
1294 // proxy. Kill it off now. That way, in case the profile is going away, the | 1292 // proxy. Kill it off now. That way, in case the profile is going away, the |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1335 } | 1333 } |
1336 | 1334 |
1337 void RenderProcessHostImpl::ResumeRequestsForView(int route_id) { | 1335 void RenderProcessHostImpl::ResumeRequestsForView(int route_id) { |
1338 widget_helper_->ResumeRequestsForView(route_id); | 1336 widget_helper_->ResumeRequestsForView(route_id); |
1339 } | 1337 } |
1340 | 1338 |
1341 IPC::ChannelProxy* RenderProcessHostImpl::GetChannel() { | 1339 IPC::ChannelProxy* RenderProcessHostImpl::GetChannel() { |
1342 return channel_.get(); | 1340 return channel_.get(); |
1343 } | 1341 } |
1344 | 1342 |
1345 RenderProcessHost::RenderWidgetHostsIterator | |
1346 RenderProcessHostImpl::GetRenderWidgetHostsIterator() { | |
1347 return RenderWidgetHostsIterator(&render_widget_hosts_); | |
1348 } | |
1349 | |
1350 bool RenderProcessHostImpl::FastShutdownForPageCount(size_t count) { | 1343 bool RenderProcessHostImpl::FastShutdownForPageCount(size_t count) { |
1351 if (render_widget_hosts_.size() == count) | 1344 if (static_cast<size_t>(GetActiveViewCount()) == count) |
1352 return FastShutdownIfPossible(); | 1345 return FastShutdownIfPossible(); |
1353 return false; | 1346 return false; |
1354 } | 1347 } |
1355 | 1348 |
1356 bool RenderProcessHostImpl::FastShutdownStarted() const { | 1349 bool RenderProcessHostImpl::FastShutdownStarted() const { |
1357 return fast_shutdown_started_; | 1350 return fast_shutdown_started_; |
1358 } | 1351 } |
1359 | 1352 |
1360 // static | 1353 // static |
1361 void RenderProcessHostImpl::RegisterHost(int host_id, RenderProcessHost* host) { | 1354 void RenderProcessHostImpl::RegisterHost(int host_id, RenderProcessHost* host) { |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 RendererClosedDetails details(GetHandle(), status, exit_code); | 1589 RendererClosedDetails details(GetHandle(), status, exit_code); |
1597 NotificationService::current()->Notify( | 1590 NotificationService::current()->Notify( |
1598 NOTIFICATION_RENDERER_PROCESS_CLOSED, | 1591 NOTIFICATION_RENDERER_PROCESS_CLOSED, |
1599 Source<RenderProcessHost>(this), | 1592 Source<RenderProcessHost>(this), |
1600 Details<RendererClosedDetails>(&details)); | 1593 Details<RendererClosedDetails>(&details)); |
1601 | 1594 |
1602 child_process_launcher_.reset(); | 1595 child_process_launcher_.reset(); |
1603 channel_.reset(); | 1596 channel_.reset(); |
1604 gpu_message_filter_ = NULL; | 1597 gpu_message_filter_ = NULL; |
1605 | 1598 |
1606 IDMap<RenderWidgetHost>::iterator iter(&render_widget_hosts_); | 1599 RenderWidgetHost::List widgets = RenderWidgetHost::GetRenderWidgetHosts(); |
1607 while (!iter.IsAtEnd()) { | 1600 for (size_t i = 0; i < widgets.size(); ++i) { |
1608 RenderWidgetHostImpl::From(iter.GetCurrentValue())->OnMessageReceived( | 1601 if (widgets[i]->GetProcess()->GetID() != GetID()) |
1609 ViewHostMsg_RenderViewGone(iter.GetCurrentKey(), | 1602 continue; |
| 1603 RenderWidgetHostImpl::From(widgets[i])->OnMessageReceived( |
| 1604 ViewHostMsg_RenderViewGone(widgets[i]->GetRoutingID(), |
1610 static_cast<int>(status), | 1605 static_cast<int>(status), |
1611 exit_code)); | 1606 exit_code)); |
1612 iter.Advance(); | |
1613 } | 1607 } |
1614 | 1608 |
1615 ClearTransportDIBCache(); | 1609 ClearTransportDIBCache(); |
1616 | 1610 |
1617 // this object is not deleted at this point and may be reused later. | 1611 // this object is not deleted at this point and may be reused later. |
1618 // TODO(darin): clean this up | 1612 // TODO(darin): clean this up |
1619 } | 1613 } |
1620 | 1614 |
1621 int RenderProcessHostImpl::GetActiveViewCount() { | 1615 int RenderProcessHostImpl::GetActiveViewCount() { |
1622 int num_active_views = 0; | 1616 int num_active_views = 0; |
1623 for (RenderWidgetHostsIterator iter = GetRenderWidgetHostsIterator(); | 1617 RenderWidgetHost::List widgets = RenderWidgetHost::GetRenderWidgetHosts(); |
1624 !iter.IsAtEnd(); | 1618 for (size_t i = 0; i < widgets.size(); ++i) { |
1625 iter.Advance()) { | 1619 // Count only RenderWidgetHosts in this process. |
1626 const RenderWidgetHost* widget = iter.GetCurrentValue(); | 1620 if (widgets[i]->GetProcess()->GetID() != GetID()) |
1627 DCHECK(widget); | |
1628 if (!widget) | |
1629 continue; | 1621 continue; |
1630 | 1622 |
1631 // All RenderWidgetHosts are swapped in. | 1623 // All RenderWidgetHosts are swapped in. |
1632 if (!widget->IsRenderView()) { | 1624 if (!widgets[i]->IsRenderView()) { |
1633 num_active_views++; | 1625 num_active_views++; |
1634 continue; | 1626 continue; |
1635 } | 1627 } |
1636 | 1628 |
1637 // Don't count swapped out views. | 1629 // Don't count swapped out views. |
1638 RenderViewHost* rvh = | 1630 RenderViewHost* rvh = RenderViewHost::From(widgets[i]); |
1639 RenderViewHost::From(const_cast<RenderWidgetHost*>(widget)); | |
1640 if (!static_cast<RenderViewHostImpl*>(rvh)->is_swapped_out()) | 1631 if (!static_cast<RenderViewHostImpl*>(rvh)->is_swapped_out()) |
1641 num_active_views++; | 1632 num_active_views++; |
1642 } | 1633 } |
1643 return num_active_views; | 1634 return num_active_views; |
1644 } | 1635 } |
1645 | 1636 |
1646 // Frame subscription API for this class is for accelerated composited path | 1637 // Frame subscription API for this class is for accelerated composited path |
1647 // only. These calls are redirected to GpuMessageFilter. | 1638 // only. These calls are redirected to GpuMessageFilter. |
1648 void RenderProcessHostImpl::BeginFrameSubscription( | 1639 void RenderProcessHostImpl::BeginFrameSubscription( |
1649 int route_id, | 1640 int route_id, |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1762 TRACE_EVENT0("renderer_host", | 1753 TRACE_EVENT0("renderer_host", |
1763 "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost"); | 1754 "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost"); |
1764 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; | 1755 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; |
1765 ack_params.sync_point = 0; | 1756 ack_params.sync_point = 0; |
1766 RenderWidgetHostImpl::AcknowledgeBufferPresent(params.route_id, | 1757 RenderWidgetHostImpl::AcknowledgeBufferPresent(params.route_id, |
1767 params.gpu_process_host_id, | 1758 params.gpu_process_host_id, |
1768 ack_params); | 1759 ack_params); |
1769 } | 1760 } |
1770 | 1761 |
1771 void RenderProcessHostImpl::OnGpuSwitching() { | 1762 void RenderProcessHostImpl::OnGpuSwitching() { |
1772 for (RenderWidgetHostsIterator iter = GetRenderWidgetHostsIterator(); | 1763 RenderWidgetHost::List widgets = RenderWidgetHost::GetRenderWidgetHosts(); |
1773 !iter.IsAtEnd(); | 1764 for (size_t i = 0; i < widgets.size(); ++i) { |
1774 iter.Advance()) { | 1765 if (!widgets[i]->IsRenderView()) |
1775 const RenderWidgetHost* widget = iter.GetCurrentValue(); | |
1776 DCHECK(widget); | |
1777 if (!widget || !widget->IsRenderView()) | |
1778 continue; | 1766 continue; |
1779 | 1767 |
1780 RenderViewHost* rvh = | 1768 // Skip widgets in other processes. |
1781 RenderViewHost::From(const_cast<RenderWidgetHost*>(widget)); | 1769 if (widgets[i]->GetProcess()->GetID() != GetID()) |
| 1770 continue; |
1782 | 1771 |
| 1772 RenderViewHost* rvh = RenderViewHost::From(widgets[i]); |
1783 rvh->UpdateWebkitPreferences(rvh->GetWebkitPreferences()); | 1773 rvh->UpdateWebkitPreferences(rvh->GetWebkitPreferences()); |
1784 } | 1774 } |
1785 } | 1775 } |
1786 | 1776 |
1787 } // namespace content | 1777 } // namespace content |
OLD | NEW |