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/command_line.h" |
| 11 #include "base/debug/alias.h" |
11 #include "base/i18n/char_iterator.h" | 12 #include "base/i18n/char_iterator.h" |
12 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
13 #include "base/time/time.h" | 14 #include "base/time/time.h" |
14 #include "content/child/appcache/appcache_dispatcher.h" | 15 #include "content/child/appcache/appcache_dispatcher.h" |
15 #include "content/child/plugin_messages.h" | 16 #include "content/child/plugin_messages.h" |
16 #include "content/child/quota_dispatcher.h" | 17 #include "content/child/quota_dispatcher.h" |
17 #include "content/child/request_extra_data.h" | 18 #include "content/child/request_extra_data.h" |
18 #include "content/child/service_worker/web_service_worker_provider_impl.h" | 19 #include "content/child/service_worker/web_service_worker_provider_impl.h" |
19 #include "content/common/frame_messages.h" | 20 #include "content/common/frame_messages.h" |
20 #include "content/common/socket_stream_handle_data.h" | 21 #include "content/common/socket_stream_handle_data.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 using blink::WebView; | 90 using blink::WebView; |
90 using base::Time; | 91 using base::Time; |
91 using base::TimeDelta; | 92 using base::TimeDelta; |
92 using webkit_glue::WebURLResponseExtraDataImpl; | 93 using webkit_glue::WebURLResponseExtraDataImpl; |
93 | 94 |
94 namespace content { | 95 namespace content { |
95 | 96 |
96 namespace { | 97 namespace { |
97 | 98 |
98 typedef std::map<blink::WebFrame*, RenderFrameImpl*> FrameMap; | 99 typedef std::map<blink::WebFrame*, RenderFrameImpl*> FrameMap; |
99 base::LazyInstance<FrameMap> g_child_frame_map = LAZY_INSTANCE_INITIALIZER; | 100 base::LazyInstance<FrameMap> g_frame_map = LAZY_INSTANCE_INITIALIZER; |
100 | 101 |
101 } // namespace | 102 } // namespace |
102 | 103 |
103 static RenderFrameImpl* (*g_create_render_frame_impl)(RenderViewImpl*, int32) = | 104 static RenderFrameImpl* (*g_create_render_frame_impl)(RenderViewImpl*, int32) = |
104 NULL; | 105 NULL; |
105 | 106 |
106 // static | 107 // static |
107 RenderFrameImpl* RenderFrameImpl::Create(RenderViewImpl* render_view, | 108 RenderFrameImpl* RenderFrameImpl::Create(RenderViewImpl* render_view, |
108 int32 routing_id) { | 109 int32 routing_id) { |
109 DCHECK(routing_id != MSG_ROUTING_NONE); | 110 DCHECK(routing_id != MSG_ROUTING_NONE); |
110 | 111 |
111 if (g_create_render_frame_impl) | 112 if (g_create_render_frame_impl) |
112 return g_create_render_frame_impl(render_view, routing_id); | 113 return g_create_render_frame_impl(render_view, routing_id); |
113 else | 114 else |
114 return new RenderFrameImpl(render_view, routing_id); | 115 return new RenderFrameImpl(render_view, routing_id); |
115 } | 116 } |
116 | 117 |
117 RenderFrameImpl* RenderFrameImpl::FindByWebFrame(blink::WebFrame* web_frame) { | 118 RenderFrameImpl* RenderFrameImpl::FindByWebFrame(blink::WebFrame* web_frame) { |
118 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | 119 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { |
119 FrameMap::iterator iter = g_child_frame_map.Get().find(web_frame); | 120 FrameMap::iterator iter = g_frame_map.Get().find(web_frame); |
120 if (iter != g_child_frame_map.Get().end()) | 121 if (iter != g_frame_map.Get().end()) |
121 return iter->second; | 122 return iter->second; |
122 } | 123 } |
123 | 124 |
124 return NULL; | 125 return NULL; |
125 } | 126 } |
126 | 127 |
127 // static | 128 // static |
128 void RenderFrameImpl::InstallCreateHook( | 129 void RenderFrameImpl::InstallCreateHook( |
129 RenderFrameImpl* (*create_render_frame_impl)(RenderViewImpl*, int32)) { | 130 RenderFrameImpl* (*create_render_frame_impl)(RenderViewImpl*, int32)) { |
130 CHECK(!g_create_render_frame_impl); | 131 CHECK(!g_create_render_frame_impl); |
(...skipping 16 matching lines...) Expand all Loading... |
147 | 148 |
148 GetContentClient()->renderer()->RenderFrameCreated(this); | 149 GetContentClient()->renderer()->RenderFrameCreated(this); |
149 } | 150 } |
150 | 151 |
151 RenderFrameImpl::~RenderFrameImpl() { | 152 RenderFrameImpl::~RenderFrameImpl() { |
152 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, RenderFrameGone()); | 153 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, RenderFrameGone()); |
153 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, OnDestruct()); | 154 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, OnDestruct()); |
154 RenderThread::Get()->RemoveRoute(routing_id_); | 155 RenderThread::Get()->RemoveRoute(routing_id_); |
155 } | 156 } |
156 | 157 |
| 158 // TODO(nasko): Overload the delete operator to overwrite the freed |
| 159 // RenderFrameImpl object and help detect potential use-after-free bug. |
| 160 // See https://crbug.com/245126#c34. |
| 161 void RenderFrameImpl::operator delete(void* ptr) { |
| 162 memset(ptr, 0xAF, sizeof(RenderFrameImpl)); |
| 163 } |
| 164 |
157 void RenderFrameImpl::MainWebFrameCreated(blink::WebFrame* frame) { | 165 void RenderFrameImpl::MainWebFrameCreated(blink::WebFrame* frame) { |
| 166 std::pair<FrameMap::iterator, bool> result = g_frame_map.Get().insert( |
| 167 std::make_pair(frame, this)); |
| 168 CHECK(result.second) << "Inserting a duplicate item."; |
| 169 |
158 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, | 170 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, |
159 WebFrameCreated(frame)); | 171 WebFrameCreated(frame)); |
160 } | 172 } |
161 | 173 |
162 void RenderFrameImpl::SetWebFrame(blink::WebFrame* web_frame) { | 174 void RenderFrameImpl::SetWebFrame(blink::WebFrame* web_frame) { |
163 DCHECK(!frame_); | 175 DCHECK(!frame_); |
164 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) | 176 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) |
165 frame_ = web_frame; | 177 frame_ = web_frame; |
166 } | 178 } |
167 | 179 |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 make_scoped_ptr(client)); | 669 make_scoped_ptr(client)); |
658 } | 670 } |
659 | 671 |
660 void RenderFrameImpl::didAccessInitialDocument(blink::WebFrame* frame) { | 672 void RenderFrameImpl::didAccessInitialDocument(blink::WebFrame* frame) { |
661 render_view_->didAccessInitialDocument(frame); | 673 render_view_->didAccessInitialDocument(frame); |
662 } | 674 } |
663 | 675 |
664 blink::WebFrame* RenderFrameImpl::createChildFrame( | 676 blink::WebFrame* RenderFrameImpl::createChildFrame( |
665 blink::WebFrame* parent, | 677 blink::WebFrame* parent, |
666 const blink::WebString& name) { | 678 const blink::WebString& name) { |
667 RenderFrameImpl* child_render_frame = this; | |
668 long long child_frame_identifier = WebFrame::generateEmbedderIdentifier(); | 679 long long child_frame_identifier = WebFrame::generateEmbedderIdentifier(); |
669 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | 680 // Synchronously notify the browser of a child frame creation to get the |
670 // Synchronously notify the browser of a child frame creation to get the | 681 // routing_id for the RenderFrame. |
671 // routing_id for the RenderFrame. | 682 int routing_id = MSG_ROUTING_NONE; |
672 int routing_id; | 683 Send(new FrameHostMsg_CreateChildFrame(routing_id_, |
673 Send(new FrameHostMsg_CreateChildFrame(routing_id_, | 684 parent->identifier(), |
674 parent->identifier(), | 685 child_frame_identifier, |
675 child_frame_identifier, | 686 base::UTF16ToUTF8(name), |
676 base::UTF16ToUTF8(name), | 687 &routing_id)); |
677 &routing_id)); | 688 CHECK_NE(routing_id, MSG_ROUTING_NONE); |
678 child_render_frame = RenderFrameImpl::Create(render_view_, routing_id); | 689 RenderFrameImpl* child_render_frame = RenderFrameImpl::Create(render_view_, |
679 } | 690 routing_id); |
680 | 691 // TODO(nasko): Over-conservative check for debugging. |
| 692 CHECK(child_render_frame); |
681 blink::WebFrame* web_frame = WebFrame::create(child_render_frame, | 693 blink::WebFrame* web_frame = WebFrame::create(child_render_frame, |
682 child_frame_identifier); | 694 child_frame_identifier); |
| 695 // TODO(nasko): Over-conservative check for debugging. |
| 696 CHECK(web_frame); |
| 697 child_render_frame->SetWebFrame(web_frame); |
683 | 698 |
684 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | 699 std::pair<FrameMap::iterator, bool> result = g_frame_map.Get().insert( |
685 child_render_frame->SetWebFrame(web_frame); | 700 std::make_pair(web_frame, child_render_frame)); |
686 g_child_frame_map.Get().insert( | 701 CHECK(result.second) << "Inserting a duplicate item."; |
687 std::make_pair(web_frame, child_render_frame)); | |
688 } else { | |
689 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, | |
690 WebFrameCreated(web_frame)); | |
691 } | |
692 | 702 |
| 703 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, |
| 704 WebFrameCreated(web_frame)); |
693 return web_frame; | 705 return web_frame; |
694 } | 706 } |
695 | 707 |
696 void RenderFrameImpl::didDisownOpener(blink::WebFrame* frame) { | 708 void RenderFrameImpl::didDisownOpener(blink::WebFrame* frame) { |
697 render_view_->didDisownOpener(frame); | 709 render_view_->didDisownOpener(frame); |
698 } | 710 } |
699 | 711 |
700 void RenderFrameImpl::frameDetached(blink::WebFrame* frame) { | 712 void RenderFrameImpl::frameDetached(blink::WebFrame* frame) { |
701 // NOTE: This function is called on the frame that is being detached and not | 713 // NOTE: This function is called on the frame that is being detached and not |
702 // the parent frame. This is different from createChildFrame() which is | 714 // the parent frame. This is different from createChildFrame() which is |
703 // called on the parent frame. | 715 // called on the parent frame. |
704 CHECK(!is_detaching_); | 716 CHECK(!is_detaching_); |
| 717 // TODO(nasko): Remove all debug::Alias lines after diagnosing failures. |
| 718 base::debug::Alias(frame); |
| 719 |
| 720 bool is_subframe = !!frame->parent(); |
| 721 base::debug::Alias(&is_subframe); |
705 | 722 |
706 int64 parent_frame_id = -1; | 723 int64 parent_frame_id = -1; |
707 if (frame->parent()) | 724 base::debug::Alias(&parent_frame_id); |
| 725 if (is_subframe) |
708 parent_frame_id = frame->parent()->identifier(); | 726 parent_frame_id = frame->parent()->identifier(); |
709 | 727 |
710 Send(new FrameHostMsg_Detach(routing_id_, parent_frame_id, | 728 Send(new FrameHostMsg_Detach(routing_id_, parent_frame_id, |
711 frame->identifier())); | 729 frame->identifier())); |
712 | 730 |
713 // Currently multiple WebCore::Frames can send frameDetached to a single | 731 // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be |
714 // RenderFrameImpl. This is legacy behavior from when RenderViewImpl served | 732 // sent before setting |is_detaching_| to true. In contrast, Observers |
715 // as a shared WebFrameClient for multiple Webcore::Frame objects. It also | 733 // should only be notified afterwards so they cannot call back into here and |
716 // prevents this class from entering the |is_detaching_| state because | 734 // have IPCs fired off. |
717 // even though one WebCore::Frame may have detached itself, others will | 735 is_detaching_ = true; |
718 // still need to use this object. | |
719 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | |
720 // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be | |
721 // sent before setting |is_detaching_| to true. In contrast, Observers | |
722 // should only be notified afterwards so they cannot call back into and | |
723 // have IPCs fired off. | |
724 is_detaching_ = true; | |
725 } | |
726 | 736 |
727 // Call back to RenderViewImpl for observers to be notified. | 737 // Call back to RenderViewImpl for observers to be notified. |
728 // TODO(nasko): Remove once we have RenderFrameObserver. | 738 // TODO(nasko): Remove once we have RenderFrameObserver. |
729 render_view_->frameDetached(frame); | 739 render_view_->frameDetached(frame); |
730 | 740 |
| 741 // We need to clean up subframes by removing them from the map and deleting |
| 742 // the RenderFrameImpl. In contrast, the main frame is owned by its |
| 743 // containing RenderViewHost (so that they have the same lifetime), so only |
| 744 // removal from the map is needed and no deletion. |
| 745 FrameMap::iterator it = g_frame_map.Get().find(frame); |
| 746 CHECK(it != g_frame_map.Get().end()); |
| 747 CHECK_EQ(it->second, this); |
| 748 g_frame_map.Get().erase(it); |
| 749 |
| 750 // |frame| is invalid after here. |
731 frame->close(); | 751 frame->close(); |
732 | 752 |
733 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { | 753 if (is_subframe) { |
734 // If the frame does not have a parent, it is the main frame. The main | 754 delete this; |
735 // frame is owned by the containing RenderViewHost so it does not require | 755 // Object is invalid after this point. |
736 // any cleanup here. | |
737 if (frame->parent()) { | |
738 FrameMap::iterator it = g_child_frame_map.Get().find(frame); | |
739 DCHECK(it != g_child_frame_map.Get().end()); | |
740 DCHECK_EQ(it->second, this); | |
741 g_child_frame_map.Get().erase(it); | |
742 delete this; | |
743 // Object is invalid after this point. | |
744 } | |
745 } | 756 } |
746 } | 757 } |
747 | 758 |
748 void RenderFrameImpl::willClose(blink::WebFrame* frame) { | 759 void RenderFrameImpl::willClose(blink::WebFrame* frame) { |
749 // Call back to RenderViewImpl for observers to be notified. | 760 // Call back to RenderViewImpl for observers to be notified. |
750 // TODO(nasko): Remove once we have RenderFrameObserver. | 761 // TODO(nasko): Remove once we have RenderFrameObserver. |
751 render_view_->willClose(frame); | 762 render_view_->willClose(frame); |
752 } | 763 } |
753 | 764 |
754 void RenderFrameImpl::didChangeName(blink::WebFrame* frame, | 765 void RenderFrameImpl::didChangeName(blink::WebFrame* frame, |
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1431 void RenderFrameImpl::AddObserver(RenderFrameObserver* observer) { | 1442 void RenderFrameImpl::AddObserver(RenderFrameObserver* observer) { |
1432 observers_.AddObserver(observer); | 1443 observers_.AddObserver(observer); |
1433 } | 1444 } |
1434 | 1445 |
1435 void RenderFrameImpl::RemoveObserver(RenderFrameObserver* observer) { | 1446 void RenderFrameImpl::RemoveObserver(RenderFrameObserver* observer) { |
1436 observer->RenderFrameGone(); | 1447 observer->RenderFrameGone(); |
1437 observers_.RemoveObserver(observer); | 1448 observers_.RemoveObserver(observer); |
1438 } | 1449 } |
1439 | 1450 |
1440 } // namespace content | 1451 } // namespace content |
OLD | NEW |