| 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 |