OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "core/frame/RemoteFrameView.h" | 5 #include "core/frame/RemoteFrameView.h" |
6 | 6 |
7 #include "core/dom/IntersectionObserverEntry.h" | 7 #include "core/dom/IntersectionObserverEntry.h" |
8 #include "core/frame/FrameView.h" | 8 #include "core/frame/FrameView.h" |
9 #include "core/frame/LocalFrame.h" | 9 #include "core/frame/LocalFrame.h" |
10 #include "core/frame/RemoteFrame.h" | 10 #include "core/frame/RemoteFrame.h" |
11 #include "core/frame/RemoteFrameClient.h" | 11 #include "core/frame/RemoteFrameClient.h" |
12 #include "core/html/HTMLFrameOwnerElement.h" | 12 #include "core/html/HTMLFrameOwnerElement.h" |
13 #include "core/layout/LayoutView.h" | 13 #include "core/layout/LayoutView.h" |
14 #include "core/layout/api/LayoutPartItem.h" | 14 #include "core/layout/api/LayoutPartItem.h" |
15 | 15 |
16 namespace blink { | 16 namespace blink { |
17 | 17 |
18 RemoteFrameView::RemoteFrameView(RemoteFrame* remote_frame) | 18 RemoteFrameView::RemoteFrameView(RemoteFrame* remote_frame) |
19 : remote_frame_(remote_frame) { | 19 : remote_frame_(remote_frame), |
| 20 parent_(nullptr), |
| 21 remote_frame_view_state_(kNotAttached) { |
20 DCHECK(remote_frame); | 22 DCHECK(remote_frame); |
21 } | 23 } |
22 | 24 |
23 RemoteFrameView::~RemoteFrameView() {} | 25 RemoteFrameView::~RemoteFrameView() {} |
24 | 26 |
25 void RemoteFrameView::SetParent(FrameView* parent) { | 27 void RemoteFrameView::SetParent(FrameView* parent) { |
| 28 if (parent) { |
| 29 SetFrameOrPluginState(kAttached); |
| 30 } |
| 31 if (!parent) { |
| 32 // Called from deferred ops just before Dispose. |
| 33 DCHECK(remote_frame_view_state_ == kAttached || |
| 34 (remote_frame_view_state_ == kDisposed && parent_)); |
| 35 SetFrameOrPluginState(kNotAttached); |
| 36 } |
| 37 |
26 if (parent == parent_) | 38 if (parent == parent_) |
27 return; | 39 return; |
28 | 40 |
29 DCHECK(!parent || !parent_); | 41 DCHECK(!parent || !parent_); |
30 if (!parent || !parent->IsVisible()) | 42 if (!parent || !parent->IsVisible()) |
31 SetParentVisible(false); | 43 SetParentVisible(false); |
32 parent_ = parent; | 44 parent_ = parent; |
33 if (parent && parent->IsVisible()) | 45 if (parent && parent->IsVisible()) |
34 SetParentVisible(true); | 46 SetParentVisible(true); |
35 FrameRectsChanged(); | 47 FrameRectsChanged(); |
| 48 |
| 49 DCHECK(parent_ == ParentFrameView()); |
| 50 } |
| 51 |
| 52 FrameView* RemoteFrameView::Parent() const { |
| 53 if (remote_frame_view_state_ == kNotAttached || |
| 54 remote_frame_view_state_ == kAttached) |
| 55 DCHECK(ParentFrameView() == parent_); |
| 56 |
| 57 return parent_; |
| 58 } |
| 59 |
| 60 FrameView* RemoteFrameView::ParentFrameView() const { |
| 61 if (remote_frame_view_state_ != kAttached) |
| 62 return nullptr; |
| 63 |
| 64 Frame* parent_frame = remote_frame_->Tree().Parent(); |
| 65 if (parent_frame && parent_frame->IsLocalFrame()) |
| 66 return ToLocalFrame(parent_frame)->View(); |
| 67 |
| 68 return nullptr; |
| 69 } |
| 70 |
| 71 void RemoteFrameView::SetFrameOrPluginState(FrameOrPluginState state) { |
| 72 VLOG(1) << "SetFrameOrPluginState " << this << " " << remote_frame_view_state_ |
| 73 << "->" << state; |
| 74 if (VLOG_IS_ON(2)) |
| 75 base::debug::StackTrace(10).Print(); |
| 76 switch (state) { |
| 77 case kNotAttached: |
| 78 DCHECK(remote_frame_view_state_ == kAttached || |
| 79 remote_frame_view_state_ == kDisposed); |
| 80 break; |
| 81 case kAttached: |
| 82 DCHECK(remote_frame_view_state_ == kNotAttached || |
| 83 remote_frame_view_state_ == kDisposed); |
| 84 break; |
| 85 case kDeferred: |
| 86 DCHECK(remote_frame_view_state_ == kNotAttached || |
| 87 remote_frame_view_state_ == kAttached || |
| 88 remote_frame_view_state_ == kDisposed); |
| 89 break; |
| 90 case kDisposed: |
| 91 DCHECK(remote_frame_view_state_ == kAttached || |
| 92 remote_frame_view_state_ == kNotAttached || |
| 93 remote_frame_view_state_ == kDisposed); |
| 94 break; |
| 95 default: |
| 96 NOTREACHED(); |
| 97 } |
| 98 remote_frame_view_state_ = state; |
36 } | 99 } |
37 | 100 |
38 RemoteFrameView* RemoteFrameView::Create(RemoteFrame* remote_frame) { | 101 RemoteFrameView* RemoteFrameView::Create(RemoteFrame* remote_frame) { |
39 RemoteFrameView* view = new RemoteFrameView(remote_frame); | 102 RemoteFrameView* view = new RemoteFrameView(remote_frame); |
40 view->Show(); | 103 view->Show(); |
41 return view; | 104 return view; |
42 } | 105 } |
43 | 106 |
44 void RemoteFrameView::UpdateRemoteViewportIntersection() { | 107 void RemoteFrameView::UpdateRemoteViewportIntersection() { |
45 if (!remote_frame_->OwnerLayoutObject()) | 108 if (!remote_frame_->OwnerLayoutObject()) |
(...skipping 27 matching lines...) Expand all Loading... |
73 | 136 |
74 if (viewport_intersection != last_viewport_intersection_) { | 137 if (viewport_intersection != last_viewport_intersection_) { |
75 remote_frame_->Client()->UpdateRemoteViewportIntersection( | 138 remote_frame_->Client()->UpdateRemoteViewportIntersection( |
76 viewport_intersection); | 139 viewport_intersection); |
77 } | 140 } |
78 | 141 |
79 last_viewport_intersection_ = viewport_intersection; | 142 last_viewport_intersection_ = viewport_intersection; |
80 } | 143 } |
81 | 144 |
82 void RemoteFrameView::Dispose() { | 145 void RemoteFrameView::Dispose() { |
| 146 SetFrameOrPluginState(kDisposed); |
| 147 |
83 HTMLFrameOwnerElement* owner_element = remote_frame_->DeprecatedLocalOwner(); | 148 HTMLFrameOwnerElement* owner_element = remote_frame_->DeprecatedLocalOwner(); |
84 // ownerElement can be null during frame swaps, because the | 149 // ownerElement can be null during frame swaps, because the |
85 // RemoteFrameView is disconnected before detachment. | 150 // RemoteFrameView is disconnected before detachment. |
86 if (owner_element && owner_element->OwnedWidget() == this) | 151 if (owner_element && owner_element->OwnedWidget() == this) |
87 owner_element->SetWidget(nullptr); | 152 owner_element->SetWidget(nullptr); |
88 } | 153 } |
89 | 154 |
90 void RemoteFrameView::InvalidateRect(const IntRect& rect) { | 155 void RemoteFrameView::InvalidateRect(const IntRect& rect) { |
91 LayoutPartItem layout_item = remote_frame_->OwnerLayoutItem(); | 156 LayoutPartItem layout_item = remote_frame_->OwnerLayoutItem(); |
92 if (layout_item.IsNull()) | 157 if (layout_item.IsNull()) |
(...skipping 11 matching lines...) Expand all Loading... |
104 | 169 |
105 frame_rect_ = frame_rect; | 170 frame_rect_ = frame_rect; |
106 FrameRectsChanged(); | 171 FrameRectsChanged(); |
107 } | 172 } |
108 | 173 |
109 void RemoteFrameView::FrameRectsChanged() { | 174 void RemoteFrameView::FrameRectsChanged() { |
110 // Update the rect to reflect the position of the frame relative to the | 175 // Update the rect to reflect the position of the frame relative to the |
111 // containing local frame root. The position of the local root within | 176 // containing local frame root. The position of the local root within |
112 // any remote frames, if any, is accounted for by the embedder. | 177 // any remote frames, if any, is accounted for by the embedder. |
113 IntRect new_rect = frame_rect_; | 178 IntRect new_rect = frame_rect_; |
114 if (parent_) | 179 |
115 new_rect = parent_->ConvertToRootFrame(parent_->ContentsToFrame(new_rect)); | 180 // TODO(joelhockey): I don't think it makes sense for this to be called |
| 181 // when it is not attached. |
| 182 // This gets called in kNotAttached state from |
| 183 // SetWidget : UpdateOnWidgetChange : UpdateGeometryInternal : |
| 184 // FrameRectsChanged however UpdateOnWidgetChange gets called before the |
| 185 // SetParent which makes this move to kAttached state. This is also called in |
| 186 // kDeferred state for SetParent(nullptr). |
| 187 DCHECK(remote_frame_view_state_ == kAttached || |
| 188 remote_frame_view_state_ == kNotAttached || |
| 189 remote_frame_view_state_ == kDisposed); |
| 190 if (FrameView* parent = ParentFrameView()) |
| 191 new_rect = parent->ConvertToRootFrame(parent->ContentsToFrame(new_rect)); |
116 remote_frame_->Client()->FrameRectsChanged(new_rect); | 192 remote_frame_->Client()->FrameRectsChanged(new_rect); |
117 } | 193 } |
118 | 194 |
119 void RemoteFrameView::Hide() { | 195 void RemoteFrameView::Hide() { |
120 self_visible_ = false; | 196 self_visible_ = false; |
121 remote_frame_->Client()->VisibilityChanged(false); | 197 remote_frame_->Client()->VisibilityChanged(false); |
122 } | 198 } |
123 | 199 |
124 void RemoteFrameView::Show() { | 200 void RemoteFrameView::Show() { |
125 self_visible_ = true; | 201 self_visible_ = true; |
126 remote_frame_->Client()->VisibilityChanged(true); | 202 remote_frame_->Client()->VisibilityChanged(true); |
127 } | 203 } |
128 | 204 |
129 void RemoteFrameView::SetParentVisible(bool visible) { | 205 void RemoteFrameView::SetParentVisible(bool visible) { |
130 if (parent_visible_ == visible) | 206 if (parent_visible_ == visible) |
131 return; | 207 return; |
132 | 208 |
133 parent_visible_ = visible; | 209 parent_visible_ = visible; |
134 if (!self_visible_) | 210 if (!self_visible_) |
135 return; | 211 return; |
136 | 212 |
137 remote_frame_->Client()->VisibilityChanged(self_visible_ && parent_visible_); | 213 remote_frame_->Client()->VisibilityChanged(self_visible_ && parent_visible_); |
138 } | 214 } |
139 | 215 |
140 IntRect RemoteFrameView::ConvertFromRootFrame( | 216 IntRect RemoteFrameView::ConvertFromRootFrame( |
141 const IntRect& rect_in_root_frame) const { | 217 const IntRect& rect_in_root_frame) const { |
142 if (parent_) { | 218 // TODO(joelhockey): I think this should only be called when in state |
143 IntRect parent_rect = parent_->ConvertFromRootFrame(rect_in_root_frame); | 219 // kAttached. However, it gets called in state kDisposed from |
| 220 // content_browsertest |
| 221 // --gtest_filter=SitePerProcessBrowserTest.SubframePendingAndBackToSameSiteIn
stance |
| 222 // Called in state kDeferred from |
| 223 // browser_tests |
| 224 // --gtest_filter=WebViewTests/WebViewTest.Shim_TestDisplayBlock/1 |
| 225 DCHECK(remote_frame_view_state_ == kAttached || |
| 226 remote_frame_view_state_ == kDeferred || |
| 227 remote_frame_view_state_ == kDisposed); |
| 228 if (FrameView* parent = ParentFrameView()) { |
| 229 IntRect parent_rect = parent->ConvertFromRootFrame(rect_in_root_frame); |
144 parent_rect.SetLocation( | 230 parent_rect.SetLocation( |
145 parent_->ConvertSelfToChild(*this, parent_rect.Location())); | 231 parent->ConvertSelfToChild(*this, parent_rect.Location())); |
146 return parent_rect; | 232 return parent_rect; |
147 } | 233 } |
148 return rect_in_root_frame; | 234 return rect_in_root_frame; |
149 } | 235 } |
150 | 236 |
151 DEFINE_TRACE(RemoteFrameView) { | 237 DEFINE_TRACE(RemoteFrameView) { |
152 visitor->Trace(remote_frame_); | 238 visitor->Trace(remote_frame_); |
153 visitor->Trace(parent_); | 239 visitor->Trace(parent_); |
154 } | 240 } |
155 | 241 |
156 } // namespace blink | 242 } // namespace blink |
OLD | NEW |