Index: third_party/WebKit/Source/web/WebPluginContainerImpl.cpp |
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp |
index 6cbf14726ace79d4fe6c51272924af9033fe9ea4..cbb2fc5cf121cf6fe12ad6a95e2611df2d4d28f7 100644 |
--- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp |
+++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp |
@@ -112,6 +112,16 @@ namespace blink { |
// Public methods -------------------------------------------------------------- |
void WebPluginContainerImpl::SetParent(FrameView* parent) { |
+ if (parent) { |
+ SetFrameOrPluginState(kAttached); |
+ DCHECK(parent == ParentFrameView()); |
+ } |
+ if (!parent) { |
+ DCHECK(plugin_state_ == kAttached || |
+ (plugin_state_ == kDisposed && parent_)); |
+ SetFrameOrPluginState(kNotAttached); |
+ } |
+ |
DCHECK(!parent || !parent_); |
if (!parent || !parent->IsVisible()) |
SetParentVisible(false); |
@@ -120,6 +130,51 @@ void WebPluginContainerImpl::SetParent(FrameView* parent) { |
SetParentVisible(true); |
} |
+FrameView* WebPluginContainerImpl::Parent() const { |
+ if ((plugin_state_ == kAttached || plugin_state_ == kNotAttached) && |
+ element_->GetDocument().GetFrame()) |
+ DCHECK(ParentFrameView() == parent_); |
+ |
+ return parent_; |
+} |
+ |
+FrameView* WebPluginContainerImpl::ParentFrameView() const { |
+ if (plugin_state_ != kAttached) |
+ return nullptr; |
+ |
+ LocalFrame* frame = element_->GetDocument().GetFrame(); |
+ if (!frame) |
+ return nullptr; |
+ |
+ return frame->View(); |
+} |
+ |
+void WebPluginContainerImpl::SetFrameOrPluginState(FrameOrPluginState state) { |
+ VLOG(1) << "SetFrameOrPluginState " << this << " " << plugin_state_ << "->" |
+ << state; |
+ if (VLOG_IS_ON(2)) |
+ base::debug::StackTrace(10).Print(); |
+ switch (state) { |
+ case kNotAttached: |
+ DCHECK(plugin_state_ == kAttached); |
+ break; |
+ case kAttached: |
+ DCHECK(plugin_state_ == kNotAttached); |
+ break; |
+ case kDeferred: |
+ DCHECK(plugin_state_ == kNotAttached || plugin_state_ == kAttached || |
+ plugin_state_ == kDeferred); |
+ break; |
+ case kDisposed: |
+ DCHECK(plugin_state_ == kNotAttached || plugin_state_ == kAttached || |
+ plugin_state_ == kDeferred || plugin_state_ == kDisposed); |
+ break; |
+ default: |
+ NOTREACHED(); |
+ } |
+ plugin_state_ = state; |
+} |
+ |
void WebPluginContainerImpl::UpdateAllLifecyclePhases() { |
if (!web_plugin_) |
return; |
@@ -129,7 +184,9 @@ void WebPluginContainerImpl::UpdateAllLifecyclePhases() { |
void WebPluginContainerImpl::Paint(GraphicsContext& context, |
const CullRect& cull_rect) const { |
- if (!parent_) |
+ DCHECK(plugin_state_ == kAttached); |
+ FrameView* parent = ParentFrameView(); |
+ if (!parent) |
return; |
// Don't paint anything if the plugin doesn't intersect. |
@@ -156,20 +213,26 @@ void WebPluginContainerImpl::Paint(GraphicsContext& context, |
// The plugin is positioned in the root frame's coordinates, so it needs to |
// be painted in them too. |
- IntPoint origin = parent_->ContentsToRootFrame(IntPoint(0, 0)); |
+ IntPoint origin = parent->ContentsToRootFrame(IntPoint(0, 0)); |
context.Translate(static_cast<float>(-origin.X()), |
static_cast<float>(-origin.Y())); |
WebCanvas* canvas = context.Canvas(); |
- IntRect window_rect = parent_->ContentsToRootFrame(cull_rect.rect_); |
+ IntRect window_rect = parent->ContentsToRootFrame(cull_rect.rect_); |
web_plugin_->Paint(canvas, window_rect); |
context.Restore(); |
} |
void WebPluginContainerImpl::InvalidateRect(const IntRect& rect) { |
- if (!parent_) |
+ // TODO(joelhockey): Usually parent should only be called when attached, |
+ // but this is also called in state kDisposed in Dispose. |
+ // Also called in state kDeferred in plugins/tabindex.html |
+ DCHECK(plugin_state_ == kAttached || plugin_state_ == kDeferred || |
+ plugin_state_ == kDisposed); |
+ FrameView* parent = ParentFrameView(); |
+ if (!parent) |
return; |
LayoutBox* layout_object = ToLayoutBox(element_->GetLayoutObject()); |
@@ -431,8 +494,10 @@ void WebPluginContainerImpl::ScheduleAnimation() { |
} |
void WebPluginContainerImpl::ReportGeometry() { |
+ DCHECK(plugin_state_ == kAttached); |
+ FrameView* parent = ParentFrameView(); |
// We cannot compute geometry without a parent or layoutObject. |
- if (!parent_ || !element_ || !element_->GetLayoutObject() || !web_plugin_) |
+ if (!parent || !element_ || !element_->GetLayoutObject() || !web_plugin_) |
return; |
IntRect window_rect, clip_rect, unobscured_rect; |
@@ -575,7 +640,14 @@ void WebPluginContainerImpl::SetWantsWheelEvents(bool wants_wheel_events) { |
if (Page* page = element_->GetDocument().GetPage()) { |
if (ScrollingCoordinator* scrolling_coordinator = |
page->GetScrollingCoordinator()) { |
- if (parent_) |
+ // TODO(joelhockey): Usually parent should only be called when in state |
+ // kAttached, but this is called by TestPlugin::Initialize in state |
+ // kNotAttached. |
+ // Called in state kDisposed in plugins/re-request-touch-events-crash.html |
+ DCHECK(plugin_state_ == kNotAttached || plugin_state_ == kAttached || |
+ plugin_state_ == kDisposed); |
+ FrameView* parent = ParentFrameView(); |
+ if (parent) |
scrolling_coordinator->NotifyGeometryChanged(); |
} |
} |
@@ -583,21 +655,25 @@ void WebPluginContainerImpl::SetWantsWheelEvents(bool wants_wheel_events) { |
WebPoint WebPluginContainerImpl::RootFrameToLocalPoint( |
const WebPoint& point_in_root_frame) { |
- if (!parent_) |
+ DCHECK(plugin_state_ == kAttached); |
+ FrameView* parent = ParentFrameView(); |
+ if (!parent) |
return point_in_root_frame; |
- WebPoint point_in_content = parent_->RootFrameToContents(point_in_root_frame); |
+ WebPoint point_in_content = parent->RootFrameToContents(point_in_root_frame); |
return RoundedIntPoint(element_->GetLayoutObject()->AbsoluteToLocal( |
FloatPoint(point_in_content), kUseTransforms)); |
} |
WebPoint WebPluginContainerImpl::LocalToRootFramePoint( |
const WebPoint& point_in_local) { |
- if (!parent_) |
+ DCHECK(plugin_state_ == kAttached); |
+ FrameView* parent = ParentFrameView(); |
+ if (!parent) |
return point_in_local; |
IntPoint absolute_point = |
RoundedIntPoint(element_->GetLayoutObject()->LocalToAbsolute( |
FloatPoint(point_in_local), kUseTransforms)); |
- return parent_->ContentsToRootFrame(absolute_point); |
+ return parent->ContentsToRootFrame(absolute_point); |
} |
void WebPluginContainerImpl::DidReceiveResponse( |
@@ -666,6 +742,8 @@ bool WebPluginContainerImpl::WantsWheelEvents() { |
WebPluginContainerImpl::WebPluginContainerImpl(HTMLPlugInElement* element, |
WebPlugin* web_plugin) |
: ContextClient(element->GetDocument().GetFrame()), |
+ parent_(nullptr), |
+ plugin_state_(kNotAttached), |
element_(element), |
web_plugin_(web_plugin), |
web_layer_(nullptr), |
@@ -682,6 +760,7 @@ WebPluginContainerImpl::~WebPluginContainerImpl() { |
void WebPluginContainerImpl::Dispose() { |
is_disposed_ = true; |
+ SetFrameOrPluginState(kDisposed); |
RequestTouchEventType(kTouchEventRequestTypeNone); |
SetWantsWheelEvents(false); |
@@ -708,12 +787,13 @@ DEFINE_TRACE(WebPluginContainerImpl) { |
void WebPluginContainerImpl::HandleMouseEvent(MouseEvent* event) { |
// We cache the parent FrameView here as the plugin widget could be deleted |
// in the call to HandleEvent. See http://b/issue?id=1362948 |
- FrameView* parent_view = parent_; |
+ DCHECK(plugin_state_ == kAttached); |
+ FrameView* parent = ParentFrameView(); |
// TODO(dtapuska): Move WebMouseEventBuilder into the anonymous namespace |
// in this class. |
WebMouseEventBuilder transformed_event( |
- parent_, LayoutItem(element_->GetLayoutObject()), *event); |
+ parent, LayoutItem(element_->GetLayoutObject()), *event); |
if (transformed_event.GetType() == WebInputEvent::kUndefined) |
return; |
@@ -729,11 +809,11 @@ void WebPluginContainerImpl::HandleMouseEvent(MouseEvent* event) { |
// A windowless plugin can change the cursor in response to a mouse move |
// event. We need to reflect the changed cursor in the frame view as the |
// mouse is moved in the boundaries of the windowless plugin. |
- Page* page = parent_view->GetFrame().GetPage(); |
+ Page* page = parent->GetFrame().GetPage(); |
if (!page) |
return; |
page->GetChromeClient().SetCursorForPlugin( |
- cursor_info, &parent_view->GetFrame().LocalFrameRoot()); |
+ cursor_info, &parent->GetFrame().LocalFrameRoot()); |
} |
void WebPluginContainerImpl::HandleDragEvent(MouseEvent* event) { |
@@ -770,9 +850,9 @@ void WebPluginContainerImpl::HandleWheelEvent(WheelEvent* event) { |
WebFloatPoint absolute_location = event->NativeEvent().PositionInRootFrame(); |
// Translate the root frame position to content coordinates. |
- if (parent_) { |
- absolute_location = parent_->RootFrameToContents(absolute_location); |
- } |
+ DCHECK(plugin_state_ == kAttached); |
+ if (FrameView* parent = ParentFrameView()) |
+ absolute_location = parent->RootFrameToContents(absolute_location); |
IntPoint local_point = |
RoundedIntPoint(element_->GetLayoutObject()->AbsoluteToLocal( |
@@ -917,8 +997,10 @@ void WebPluginContainerImpl::HandleGestureEvent(GestureEvent* event) { |
} |
void WebPluginContainerImpl::SynthesizeMouseEventIfPossible(TouchEvent* event) { |
+ DCHECK(plugin_state_ == kAttached); |
+ FrameView* parent = ParentFrameView(); |
WebMouseEventBuilder web_event( |
- parent_, LayoutItem(element_->GetLayoutObject()), *event); |
+ parent, LayoutItem(element_->GetLayoutObject()), *event); |
if (web_event.GetType() == WebInputEvent::kUndefined) |
return; |
@@ -930,14 +1012,13 @@ void WebPluginContainerImpl::SynthesizeMouseEventIfPossible(TouchEvent* event) { |
} |
void WebPluginContainerImpl::FocusPlugin() { |
- LocalFrame& containing_frame = parent_->GetFrame(); |
- if (Page* current_page = containing_frame.GetPage()) |
- current_page->GetFocusController().SetFocusedElement(element_, |
- &containing_frame); |
- else |
- containing_frame.GetDocument()->SetFocusedElement( |
+ if (Page* current_page = GetFrame()->GetPage()) { |
+ current_page->GetFocusController().SetFocusedElement(element_, GetFrame()); |
+ } else { |
+ GetFrame()->GetDocument()->SetFocusedElement( |
element_, FocusParams(SelectionBehaviorOnFocus::kNone, |
kWebFocusTypeNone, nullptr)); |
+ } |
} |
void WebPluginContainerImpl::IssuePaintInvalidations() { |