Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: content/renderer/render_frame_impl.cc

Issue 1409693009: Fix leaking of RenderFrames. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased on ToT and couple of more nits fixes. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/renderer/render_frame_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "content/renderer/render_frame_impl.h" 5 #include "content/renderer/render_frame_impl.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 if (previous_sibling_proxy) 697 if (previous_sibling_proxy)
698 previous_sibling_web_frame = previous_sibling_proxy->web_frame(); 698 previous_sibling_web_frame = previous_sibling_proxy->web_frame();
699 699
700 // Create the RenderFrame and WebLocalFrame, linking the two. 700 // Create the RenderFrame and WebLocalFrame, linking the two.
701 render_frame = 701 render_frame =
702 RenderFrameImpl::Create(parent_proxy->render_view(), routing_id); 702 RenderFrameImpl::Create(parent_proxy->render_view(), routing_id);
703 web_frame = parent_web_frame->createLocalChild( 703 web_frame = parent_web_frame->createLocalChild(
704 replicated_state.scope, WebString::fromUTF8(replicated_state.name), 704 replicated_state.scope, WebString::fromUTF8(replicated_state.name),
705 replicated_state.sandbox_flags, render_frame, 705 replicated_state.sandbox_flags, render_frame,
706 previous_sibling_web_frame, frame_owner_properties); 706 previous_sibling_web_frame, frame_owner_properties);
707
708 // The RenderFrame is created and inserted into the frame tree in the above
709 // call to createLocalChild.
710 render_frame->in_frame_tree_ = true;
707 } else { 711 } else {
708 RenderFrameProxy* proxy = 712 RenderFrameProxy* proxy =
709 RenderFrameProxy::FromRoutingID(proxy_routing_id); 713 RenderFrameProxy::FromRoutingID(proxy_routing_id);
710 // The remote frame could've been detached while the remote-to-local 714 // The remote frame could've been detached while the remote-to-local
711 // navigation was being initiated in the browser process. Drop the 715 // navigation was being initiated in the browser process. Drop the
712 // navigation and don't create the frame in that case. See 716 // navigation and don't create the frame in that case. See
713 // https://crbug.com/526304. 717 // https://crbug.com/526304.
714 if (!proxy) 718 if (!proxy)
715 return; 719 return;
716 720
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 return opener_frame->GetWebFrame(); 805 return opener_frame->GetWebFrame();
802 } 806 }
803 807
804 return nullptr; 808 return nullptr;
805 } 809 }
806 810
807 // RenderFrameImpl ---------------------------------------------------------- 811 // RenderFrameImpl ----------------------------------------------------------
808 RenderFrameImpl::RenderFrameImpl(const CreateParams& params) 812 RenderFrameImpl::RenderFrameImpl(const CreateParams& params)
809 : frame_(NULL), 813 : frame_(NULL),
810 is_main_frame_(true), 814 is_main_frame_(true),
815 in_browser_initiated_detach_(false),
816 in_frame_tree_(false),
811 render_view_(params.render_view->AsWeakPtr()), 817 render_view_(params.render_view->AsWeakPtr()),
812 routing_id_(params.routing_id), 818 routing_id_(params.routing_id),
813 is_swapped_out_(false), 819 is_swapped_out_(false),
814 render_frame_proxy_(NULL), 820 render_frame_proxy_(NULL),
815 is_detaching_(false), 821 is_detaching_(false),
816 proxy_routing_id_(MSG_ROUTING_NONE), 822 proxy_routing_id_(MSG_ROUTING_NONE),
817 #if defined(ENABLE_PLUGINS) 823 #if defined(ENABLE_PLUGINS)
818 plugin_power_saver_helper_(nullptr), 824 plugin_power_saver_helper_(nullptr),
819 #endif 825 #endif
820 cookie_jar_(this), 826 cookie_jar_(this),
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
1204 while ((observer = it.GetNext()) != NULL) { 1210 while ((observer = it.GetNext()) != NULL) {
1205 if (observer->OnMessageReceived(msg)) 1211 if (observer->OnMessageReceived(msg))
1206 return true; 1212 return true;
1207 } 1213 }
1208 1214
1209 bool handled = true; 1215 bool handled = true;
1210 IPC_BEGIN_MESSAGE_MAP(RenderFrameImpl, msg) 1216 IPC_BEGIN_MESSAGE_MAP(RenderFrameImpl, msg)
1211 IPC_MESSAGE_HANDLER(FrameMsg_Navigate, OnNavigate) 1217 IPC_MESSAGE_HANDLER(FrameMsg_Navigate, OnNavigate)
1212 IPC_MESSAGE_HANDLER(FrameMsg_BeforeUnload, OnBeforeUnload) 1218 IPC_MESSAGE_HANDLER(FrameMsg_BeforeUnload, OnBeforeUnload)
1213 IPC_MESSAGE_HANDLER(FrameMsg_SwapOut, OnSwapOut) 1219 IPC_MESSAGE_HANDLER(FrameMsg_SwapOut, OnSwapOut)
1220 IPC_MESSAGE_HANDLER(FrameMsg_Delete, OnDeleteFrame)
1214 IPC_MESSAGE_HANDLER(FrameMsg_Stop, OnStop) 1221 IPC_MESSAGE_HANDLER(FrameMsg_Stop, OnStop)
1215 IPC_MESSAGE_HANDLER(FrameMsg_ContextMenuClosed, OnContextMenuClosed) 1222 IPC_MESSAGE_HANDLER(FrameMsg_ContextMenuClosed, OnContextMenuClosed)
1216 IPC_MESSAGE_HANDLER(FrameMsg_CustomContextMenuAction, 1223 IPC_MESSAGE_HANDLER(FrameMsg_CustomContextMenuAction,
1217 OnCustomContextMenuAction) 1224 OnCustomContextMenuAction)
1218 IPC_MESSAGE_HANDLER(InputMsg_Undo, OnUndo) 1225 IPC_MESSAGE_HANDLER(InputMsg_Undo, OnUndo)
1219 IPC_MESSAGE_HANDLER(InputMsg_Redo, OnRedo) 1226 IPC_MESSAGE_HANDLER(InputMsg_Redo, OnRedo)
1220 IPC_MESSAGE_HANDLER(InputMsg_Cut, OnCut) 1227 IPC_MESSAGE_HANDLER(InputMsg_Cut, OnCut)
1221 IPC_MESSAGE_HANDLER(InputMsg_Copy, OnCopy) 1228 IPC_MESSAGE_HANDLER(InputMsg_Copy, OnCopy)
1222 IPC_MESSAGE_HANDLER(InputMsg_Paste, OnPaste) 1229 IPC_MESSAGE_HANDLER(InputMsg_Paste, OnPaste)
1223 IPC_MESSAGE_HANDLER(InputMsg_PasteAndMatchStyle, OnPasteAndMatchStyle) 1230 IPC_MESSAGE_HANDLER(InputMsg_PasteAndMatchStyle, OnPasteAndMatchStyle)
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 proxy->SetReplicatedState(replicated_frame_state); 1466 proxy->SetReplicatedState(replicated_frame_state);
1460 1467
1461 // Safe to exit if no one else is using the process. 1468 // Safe to exit if no one else is using the process.
1462 // TODO(nasko): Remove the dependency on RenderViewImpl here and ref count 1469 // TODO(nasko): Remove the dependency on RenderViewImpl here and ref count
1463 // the process based on the lifetime of this RenderFrameImpl object. 1470 // the process based on the lifetime of this RenderFrameImpl object.
1464 if (is_main_frame) { 1471 if (is_main_frame) {
1465 render_view->WasSwappedOut(); 1472 render_view->WasSwappedOut();
1466 } 1473 }
1467 } 1474 }
1468 1475
1476 void RenderFrameImpl::OnDeleteFrame() {
1477 // TODO(nasko): If this message is received right after a commit has
1478 // swapped a RenderFrameProxy with this RenderFrame, the proxy needs to be
1479 // recreated in addition to the RenderFrame being deleted.
1480 // See https://crbug.com/569683 for details.
1481 in_browser_initiated_detach_ = true;
1482
1483 // This will result in a call to RendeFrameImpl::frameDetached, which
1484 // deletes the object. Do not access |this| after detach.
1485 frame_->detach();
1486 }
1487
1469 void RenderFrameImpl::OnContextMenuClosed( 1488 void RenderFrameImpl::OnContextMenuClosed(
1470 const CustomContextMenuContext& custom_context) { 1489 const CustomContextMenuContext& custom_context) {
1471 if (custom_context.request_id) { 1490 if (custom_context.request_id) {
1472 // External request, should be in our map. 1491 // External request, should be in our map.
1473 ContextMenuClient* client = 1492 ContextMenuClient* client =
1474 pending_context_menus_.Lookup(custom_context.request_id); 1493 pending_context_menus_.Lookup(custom_context.request_id);
1475 if (client) { 1494 if (client) {
1476 client->OnMenuClosed(custom_context.request_id); 1495 client->OnMenuClosed(custom_context.request_id);
1477 pending_context_menus_.Remove(custom_context.request_id); 1496 pending_context_menus_.Remove(custom_context.request_id);
1478 } 1497 }
(...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after
2460 2479
2461 // Create the RenderFrame and WebLocalFrame, linking the two. 2480 // Create the RenderFrame and WebLocalFrame, linking the two.
2462 RenderFrameImpl* child_render_frame = RenderFrameImpl::Create( 2481 RenderFrameImpl* child_render_frame = RenderFrameImpl::Create(
2463 render_view_.get(), child_routing_id); 2482 render_view_.get(), child_routing_id);
2464 blink::WebLocalFrame* web_frame = 2483 blink::WebLocalFrame* web_frame =
2465 WebLocalFrame::create(scope, child_render_frame); 2484 WebLocalFrame::create(scope, child_render_frame);
2466 child_render_frame->SetWebFrame(web_frame); 2485 child_render_frame->SetWebFrame(web_frame);
2467 2486
2468 // Add the frame to the frame tree and initialize it. 2487 // Add the frame to the frame tree and initialize it.
2469 parent->appendChild(web_frame); 2488 parent->appendChild(web_frame);
2489 child_render_frame->in_frame_tree_ = true;
2470 child_render_frame->Initialize(); 2490 child_render_frame->Initialize();
2471 2491
2472 return web_frame; 2492 return web_frame;
2473 } 2493 }
2474 2494
2475 void RenderFrameImpl::didChangeOpener(blink::WebFrame* opener) { 2495 void RenderFrameImpl::didChangeOpener(blink::WebFrame* opener) {
2476 // Only active frames are able to disown their opener. 2496 // Only active frames are able to disown their opener.
2477 if (!opener && is_swapped_out_) 2497 if (!opener && is_swapped_out_)
2478 return; 2498 return;
2479 2499
(...skipping 11 matching lines...) Expand all
2491 // the parent frame. This is different from createChildFrame() which is 2511 // the parent frame. This is different from createChildFrame() which is
2492 // called on the parent frame. 2512 // called on the parent frame.
2493 CHECK(!is_detaching_); 2513 CHECK(!is_detaching_);
2494 DCHECK(!frame_ || frame_ == frame); 2514 DCHECK(!frame_ || frame_ == frame);
2495 2515
2496 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, FrameDetached()); 2516 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, FrameDetached());
2497 FOR_EACH_OBSERVER(RenderViewObserver, render_view_->observers(), 2517 FOR_EACH_OBSERVER(RenderViewObserver, render_view_->observers(),
2498 FrameDetached(frame)); 2518 FrameDetached(frame));
2499 2519
2500 // We only notify the browser process when the frame is being detached for 2520 // We only notify the browser process when the frame is being detached for
2501 // removal. If the frame is being detached for swap, we don't need to do this 2521 // removal and it was initiated from the renderer process.
2502 // since we are not modifiying the frame tree. 2522 if (!in_browser_initiated_detach_ && type == DetachType::Remove)
2503 if (type == DetachType::Remove)
2504 Send(new FrameHostMsg_Detach(routing_id_)); 2523 Send(new FrameHostMsg_Detach(routing_id_));
2505 2524
2506 // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be 2525 // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be
2507 // sent before setting |is_detaching_| to true. 2526 // sent before setting |is_detaching_| to true.
2508 is_detaching_ = true; 2527 is_detaching_ = true;
2509 2528
2510 // Clean up the associated RenderWidget for the frame, if there is one. 2529 // Clean up the associated RenderWidget for the frame, if there is one.
2511 if (render_widget_) { 2530 if (render_widget_) {
2512 render_widget_->UnregisterRenderFrame(this); 2531 render_widget_->UnregisterRenderFrame(this);
2513 render_widget_->CloseForFrame(); 2532 render_widget_->CloseForFrame();
2514 } 2533 }
2515 2534
2516 // We need to clean up subframes by removing them from the map and deleting 2535 // We need to clean up subframes by removing them from the map and deleting
2517 // the RenderFrameImpl. In contrast, the main frame is owned by its 2536 // the RenderFrameImpl. In contrast, the main frame is owned by its
2518 // containing RenderViewHost (so that they have the same lifetime), so only 2537 // containing RenderViewHost (so that they have the same lifetime), so only
2519 // removal from the map is needed and no deletion. 2538 // removal from the map is needed and no deletion.
2520 FrameMap::iterator it = g_frame_map.Get().find(frame); 2539 FrameMap::iterator it = g_frame_map.Get().find(frame);
2521 CHECK(it != g_frame_map.Get().end()); 2540 CHECK(it != g_frame_map.Get().end());
2522 CHECK_EQ(it->second, this); 2541 CHECK_EQ(it->second, this);
2523 g_frame_map.Get().erase(it); 2542 g_frame_map.Get().erase(it);
2524 2543
2525 // Only remove the frame from the renderer's frame tree if the frame is 2544 // Only remove the frame from the renderer's frame tree if the frame is
2526 // being detached for removal. In the case of a swap, the frame needs to 2545 // being detached for removal and is already inserted in the frame tree.
2527 // remain in the tree so WebFrame::swap() can replace it with the new frame. 2546 // In the case of a swap, the frame needs to remain in the tree so
2528 if (!is_main_frame_ && type == DetachType::Remove) 2547 // WebFrame::swap() can replace it with the new frame.
2548 if (!is_main_frame_ && in_frame_tree_ &&
2549 type == DetachType::Remove) {
2529 frame->parent()->removeChild(frame); 2550 frame->parent()->removeChild(frame);
2551 }
2530 2552
2531 // |frame| is invalid after here. Be sure to clear frame_ as well, since this 2553 // |frame| is invalid after here. Be sure to clear frame_ as well, since this
2532 // object may not be deleted immediately and other methods may try to access 2554 // object may not be deleted immediately and other methods may try to access
2533 // it. 2555 // it.
2534 frame->close(); 2556 frame->close();
2535 frame_ = nullptr; 2557 frame_ = nullptr;
2536 2558
2537 delete this; 2559 delete this;
2538 // Object is invalid after this point. 2560 // Object is invalid after this point.
2539 } 2561 }
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
2957 // being navigated. In that case, don't swap the frame back in the tree 2979 // being navigated. In that case, don't swap the frame back in the tree
2958 // and return early (to avoid sending confusing IPCs to the browser 2980 // and return early (to avoid sending confusing IPCs to the browser
2959 // process). See https://crbug.com/526304 and https://crbug.com/568676. 2981 // process). See https://crbug.com/526304 and https://crbug.com/568676.
2960 // TODO(nasko, alexmos): Eventually, the browser process will send an IPC 2982 // TODO(nasko, alexmos): Eventually, the browser process will send an IPC
2961 // to clean this frame up after https://crbug.com/548275 is fixed. 2983 // to clean this frame up after https://crbug.com/548275 is fixed.
2962 if (!proxy) 2984 if (!proxy)
2963 return; 2985 return;
2964 2986
2965 proxy->web_frame()->swap(frame_); 2987 proxy->web_frame()->swap(frame_);
2966 proxy_routing_id_ = MSG_ROUTING_NONE; 2988 proxy_routing_id_ = MSG_ROUTING_NONE;
2989 in_frame_tree_ = true;
2967 2990
2968 // If this is the main frame going from a remote frame to a local frame, 2991 // If this is the main frame going from a remote frame to a local frame,
2969 // it needs to set RenderViewImpl's pointer for the main frame to itself 2992 // it needs to set RenderViewImpl's pointer for the main frame to itself
2970 // and ensure RenderWidget is no longer in swapped out mode. 2993 // and ensure RenderWidget is no longer in swapped out mode.
2971 if (is_main_frame_) { 2994 if (is_main_frame_) {
2972 CHECK(!render_view_->main_render_frame_); 2995 CHECK(!render_view_->main_render_frame_);
2973 render_view_->main_render_frame_ = this; 2996 render_view_->main_render_frame_ = this;
2974 if (render_view_->is_swapped_out()) 2997 if (render_view_->is_swapped_out())
2975 render_view_->SetSwappedOut(false); 2998 render_view_->SetSwappedOut(false);
2976 } 2999 }
(...skipping 2635 matching lines...) Expand 10 before | Expand all | Expand 10 after
5612 media::ConvertToSwitchOutputDeviceCB(web_callbacks); 5635 media::ConvertToSwitchOutputDeviceCB(web_callbacks);
5613 scoped_refptr<media::AudioOutputDevice> device = 5636 scoped_refptr<media::AudioOutputDevice> device =
5614 AudioDeviceFactory::NewOutputDevice(routing_id_, 0, sink_id.utf8(), 5637 AudioDeviceFactory::NewOutputDevice(routing_id_, 0, sink_id.utf8(),
5615 security_origin); 5638 security_origin);
5616 media::OutputDeviceStatus status = device->GetDeviceStatus(); 5639 media::OutputDeviceStatus status = device->GetDeviceStatus();
5617 device->Stop(); 5640 device->Stop();
5618 callback.Run(status); 5641 callback.Run(status);
5619 } 5642 }
5620 5643
5621 } // namespace content 5644 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/render_frame_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698