OLD | NEW |
---|---|
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 | 9 |
10 #include "base/command_line.h" | 10 #include "base/debug/alias.h" |
11 #include "base/i18n/char_iterator.h" | 11 #include "base/i18n/char_iterator.h" |
12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
14 #include "content/child/appcache/appcache_dispatcher.h" | 14 #include "content/child/appcache/appcache_dispatcher.h" |
15 #include "content/child/plugin_messages.h" | 15 #include "content/child/plugin_messages.h" |
16 #include "content/child/quota_dispatcher.h" | 16 #include "content/child/quota_dispatcher.h" |
17 #include "content/child/request_extra_data.h" | 17 #include "content/child/request_extra_data.h" |
18 #include "content/child/service_worker/web_service_worker_provider_impl.h" | 18 #include "content/child/service_worker/web_service_worker_provider_impl.h" |
19 #include "content/common/frame_messages.h" | 19 #include "content/common/frame_messages.h" |
20 #include "content/common/socket_stream_handle_data.h" | 20 #include "content/common/socket_stream_handle_data.h" |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
136 | 136 |
137 GetContentClient()->renderer()->RenderFrameCreated(this); | 137 GetContentClient()->renderer()->RenderFrameCreated(this); |
138 } | 138 } |
139 | 139 |
140 RenderFrameImpl::~RenderFrameImpl() { | 140 RenderFrameImpl::~RenderFrameImpl() { |
141 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, RenderFrameGone()); | 141 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, RenderFrameGone()); |
142 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, OnDestruct()); | 142 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, OnDestruct()); |
143 RenderThread::Get()->RemoveRoute(routing_id_); | 143 RenderThread::Get()->RemoveRoute(routing_id_); |
144 } | 144 } |
145 | 145 |
146 // TODO(nasko): Overload the delete operator to overwrite the freed | |
147 // RenderFrameImpl object and help detect potential use-after-free bug. | |
148 // See https://crbug.com/245126#c34. | |
149 void RenderFrameImpl::operator delete(void* ptr) { | |
150 memset(ptr, 0xAF, sizeof(RenderFrameImpl)); | |
151 } | |
152 | |
146 void RenderFrameImpl::MainWebFrameCreated(blink::WebFrame* frame) { | 153 void RenderFrameImpl::MainWebFrameCreated(blink::WebFrame* frame) { |
147 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, | 154 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, |
148 WebFrameCreated(frame)); | 155 WebFrameCreated(frame)); |
149 } | 156 } |
150 | 157 |
151 RenderWidget* RenderFrameImpl::GetRenderWidget() { | 158 RenderWidget* RenderFrameImpl::GetRenderWidget() { |
152 return render_view_; | 159 return render_view_; |
153 } | 160 } |
154 | 161 |
155 #if defined(ENABLE_PLUGINS) | 162 #if defined(ENABLE_PLUGINS) |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
595 make_scoped_ptr(client)); | 602 make_scoped_ptr(client)); |
596 } | 603 } |
597 | 604 |
598 void RenderFrameImpl::didAccessInitialDocument(blink::WebFrame* frame) { | 605 void RenderFrameImpl::didAccessInitialDocument(blink::WebFrame* frame) { |
599 render_view_->didAccessInitialDocument(frame); | 606 render_view_->didAccessInitialDocument(frame); |
600 } | 607 } |
601 | 608 |
602 blink::WebFrame* RenderFrameImpl::createChildFrame( | 609 blink::WebFrame* RenderFrameImpl::createChildFrame( |
603 blink::WebFrame* parent, | 610 blink::WebFrame* parent, |
604 const blink::WebString& name) { | 611 const blink::WebString& name) { |
605 RenderFrameImpl* child_render_frame = this; | |
606 long long child_frame_identifier = WebFrame::generateEmbedderIdentifier(); | 612 long long child_frame_identifier = WebFrame::generateEmbedderIdentifier(); |
607 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | 613 // Synchronously notify the browser of a child frame creation to get the |
608 // Synchronously notify the browser of a child frame creation to get the | 614 // routing_id for the RenderFrame. |
609 // routing_id for the RenderFrame. | 615 int routing_id = MSG_ROUTING_NONE; |
610 int routing_id; | 616 Send(new FrameHostMsg_CreateChildFrame(routing_id_, |
611 Send(new FrameHostMsg_CreateChildFrame(routing_id_, | 617 parent->identifier(), |
612 parent->identifier(), | 618 child_frame_identifier, |
613 child_frame_identifier, | 619 base::UTF16ToUTF8(name), |
614 base::UTF16ToUTF8(name), | 620 &routing_id)); |
615 &routing_id)); | 621 if (routing_id == MSG_ROUTING_NONE) |
jam
2013/12/27 22:24:40
this can't happen, so no need to add code to handl
| |
616 child_render_frame = RenderFrameImpl::Create(render_view_, routing_id); | 622 return NULL; |
617 } | 623 RenderFrameImpl* child_render_frame = RenderFrameImpl::Create(render_view_, |
618 | 624 routing_id); |
625 // TODO(nasko): Over-conservative check for debugging. | |
626 CHECK(child_render_frame); | |
619 blink::WebFrame* web_frame = WebFrame::create(child_render_frame, | 627 blink::WebFrame* web_frame = WebFrame::create(child_render_frame, |
620 child_frame_identifier); | 628 child_frame_identifier); |
629 // TODO(nasko): Over-conservative check for debugging. | |
630 CHECK(web_frame); | |
621 | 631 |
622 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | 632 std::pair<FrameMap::iterator, bool> result = g_child_frame_map.Get().insert( |
623 g_child_frame_map.Get().insert( | 633 std::make_pair(web_frame, child_render_frame)); |
624 std::make_pair(web_frame, child_render_frame)); | 634 CHECK(result.second) << "Inserting a duplicate item!"; |
625 } else { | |
626 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, | |
627 WebFrameCreated(web_frame)); | |
628 } | |
629 | 635 |
636 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, | |
637 WebFrameCreated(web_frame)); | |
630 return web_frame; | 638 return web_frame; |
631 } | 639 } |
632 | 640 |
633 void RenderFrameImpl::didDisownOpener(blink::WebFrame* frame) { | 641 void RenderFrameImpl::didDisownOpener(blink::WebFrame* frame) { |
634 render_view_->didDisownOpener(frame); | 642 render_view_->didDisownOpener(frame); |
635 } | 643 } |
636 | 644 |
637 void RenderFrameImpl::frameDetached(blink::WebFrame* frame) { | 645 void RenderFrameImpl::frameDetached(blink::WebFrame* frame) { |
638 // NOTE: This function is called on the frame that is being detached and not | 646 // NOTE: This function is called on the frame that is being detached and not |
639 // the parent frame. This is different from createChildFrame() which is | 647 // the parent frame. This is different from createChildFrame() which is |
640 // called on the parent frame. | 648 // called on the parent frame. |
641 CHECK(!is_detaching_); | 649 CHECK(!is_detaching_); |
650 // TODO(nasko): Remove all debug::Alias lines after diagnosing failures. | |
651 base::debug::Alias(frame); | |
652 | |
653 bool is_subframe = !!frame->parent(); | |
654 base::debug::Alias(&is_subframe); | |
642 | 655 |
643 int64 parent_frame_id = -1; | 656 int64 parent_frame_id = -1; |
644 if (frame->parent()) | 657 base::debug::Alias(&parent_frame_id); |
658 if (is_subframe) | |
645 parent_frame_id = frame->parent()->identifier(); | 659 parent_frame_id = frame->parent()->identifier(); |
646 | 660 |
647 Send(new FrameHostMsg_Detach(routing_id_, parent_frame_id, | 661 Send(new FrameHostMsg_Detach(routing_id_, parent_frame_id, |
648 frame->identifier())); | 662 frame->identifier())); |
649 | 663 |
650 // Currently multiple WebCore::Frames can send frameDetached to a single | 664 // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be |
651 // RenderFrameImpl. This is legacy behavior from when RenderViewImpl served | 665 // sent before setting |is_detaching_| to true. In contrast, Observers |
652 // as a shared WebFrameClient for multiple Webcore::Frame objects. It also | 666 // should only be notified afterwards so they cannot call back into here and |
653 // prevents this class from entering the |is_detaching_| state because | 667 // have IPCs fired off. |
654 // even though one WebCore::Frame may have detached itself, others will | 668 is_detaching_ = true; |
655 // still need to use this object. | |
656 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | |
657 // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be | |
658 // sent before setting |is_detaching_| to true. In contrast, Observers | |
659 // should only be notified afterwards so they cannot call back into and | |
660 // have IPCs fired off. | |
661 is_detaching_ = true; | |
662 } | |
663 | 669 |
664 // Call back to RenderViewImpl for observers to be notified. | 670 // Call back to RenderViewImpl for observers to be notified. |
665 // TODO(nasko): Remove once we have RenderFrameObserver. | 671 // TODO(nasko): Remove once we have RenderFrameObserver. |
666 render_view_->frameDetached(frame); | 672 render_view_->frameDetached(frame); |
667 | 673 |
674 // We need to clean up subframes by removing them from the map and deleting | |
675 // the RenderFrameImpl. In contrast, the main frame is owned by its | |
676 // containing RenderViewHost (so that they have the same lifetime), so it does | |
677 // not require any cleanup here. | |
678 if (is_subframe) { | |
679 FrameMap::iterator it = g_child_frame_map.Get().find(frame); | |
680 CHECK(it != g_child_frame_map.Get().end()); | |
681 CHECK_EQ(it->second, this); | |
682 g_child_frame_map.Get().erase(it); | |
683 } | |
684 | |
685 // |frame| is invalid after here. | |
668 frame->close(); | 686 frame->close(); |
669 | 687 |
670 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | 688 if (is_subframe) { |
671 // If the frame does not have a parent, it is the main frame. The main | 689 delete this; |
672 // frame is owned by the containing RenderViewHost so it does not require | 690 // Object is invalid after this point. |
673 // any cleanup here. | |
674 if (frame->parent()) { | |
675 FrameMap::iterator it = g_child_frame_map.Get().find(frame); | |
676 DCHECK(it != g_child_frame_map.Get().end()); | |
677 DCHECK_EQ(it->second, this); | |
678 g_child_frame_map.Get().erase(it); | |
679 delete this; | |
680 // Object is invalid after this point. | |
681 } | |
682 } | 691 } |
683 } | 692 } |
684 | 693 |
685 void RenderFrameImpl::willClose(blink::WebFrame* frame) { | 694 void RenderFrameImpl::willClose(blink::WebFrame* frame) { |
686 // Call back to RenderViewImpl for observers to be notified. | 695 // Call back to RenderViewImpl for observers to be notified. |
687 // TODO(nasko): Remove once we have RenderFrameObserver. | 696 // TODO(nasko): Remove once we have RenderFrameObserver. |
688 render_view_->willClose(frame); | 697 render_view_->willClose(frame); |
689 } | 698 } |
690 | 699 |
691 void RenderFrameImpl::didChangeName(blink::WebFrame* frame, | 700 void RenderFrameImpl::didChangeName(blink::WebFrame* frame, |
(...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1366 void RenderFrameImpl::AddObserver(RenderFrameObserver* observer) { | 1375 void RenderFrameImpl::AddObserver(RenderFrameObserver* observer) { |
1367 observers_.AddObserver(observer); | 1376 observers_.AddObserver(observer); |
1368 } | 1377 } |
1369 | 1378 |
1370 void RenderFrameImpl::RemoveObserver(RenderFrameObserver* observer) { | 1379 void RenderFrameImpl::RemoveObserver(RenderFrameObserver* observer) { |
1371 observer->RenderFrameGone(); | 1380 observer->RenderFrameGone(); |
1372 observers_.RemoveObserver(observer); | 1381 observers_.RemoveObserver(observer); |
1373 } | 1382 } |
1374 | 1383 |
1375 } // namespace content | 1384 } // namespace content |
OLD | NEW |