LCOV - code coverage report
Current view: top level - layout/generic - nsPluginFrame.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 704 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 77 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : // vim:set ts=2 sts=2 sw=2 et cin:
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : /* rendering objects for replaced elements implemented by a plugin */
       8             : 
       9             : #include "nsPluginFrame.h"
      10             : 
      11             : #include "gfx2DGlue.h"
      12             : #include "gfxContext.h"
      13             : #include "gfxMatrix.h"
      14             : #include "mozilla/gfx/2D.h"
      15             : #include "mozilla/BasicEvents.h"
      16             : #include "mozilla/MouseEvents.h"
      17             : #ifdef XP_WIN
      18             : // This is needed for DoublePassRenderingEvent.
      19             : #include "mozilla/plugins/PluginMessageUtils.h"
      20             : #endif
      21             : 
      22             : #include "nscore.h"
      23             : #include "nsCOMPtr.h"
      24             : #include "nsPresContext.h"
      25             : #include "nsIPresShell.h"
      26             : #include "nsWidgetsCID.h"
      27             : #include "nsView.h"
      28             : #include "nsViewManager.h"
      29             : #include "nsString.h"
      30             : #include "nsGkAtoms.h"
      31             : #include "nsIPluginInstanceOwner.h"
      32             : #include "nsNPAPIPluginInstance.h"
      33             : #include "nsIDOMElement.h"
      34             : #include "npapi.h"
      35             : #include "nsIObjectLoadingContent.h"
      36             : #include "nsContentUtils.h"
      37             : #include "nsDisplayList.h"
      38             : #include "nsFocusManager.h"
      39             : #include "nsLayoutUtils.h"
      40             : #include "nsFrameManager.h"
      41             : #include "nsIObserverService.h"
      42             : #include "GeckoProfiler.h"
      43             : #include <algorithm>
      44             : 
      45             : #include "nsIObjectFrame.h"
      46             : #include "nsPluginNativeWindow.h"
      47             : #include "FrameLayerBuilder.h"
      48             : 
      49             : #include "ImageLayers.h"
      50             : #include "nsPluginInstanceOwner.h"
      51             : 
      52             : #ifdef XP_WIN
      53             : #include "gfxWindowsNativeDrawing.h"
      54             : #include "gfxWindowsSurface.h"
      55             : #endif
      56             : 
      57             : #include "Layers.h"
      58             : #include "ReadbackLayer.h"
      59             : #include "ImageContainer.h"
      60             : 
      61             : // accessibility support
      62             : #ifdef ACCESSIBILITY
      63             : #include "nsAccessibilityService.h"
      64             : #endif
      65             : 
      66             : #include "mozilla/Logging.h"
      67             : 
      68             : #ifdef XP_MACOSX
      69             : #include "gfxQuartzNativeDrawing.h"
      70             : #include "mozilla/gfx/QuartzSupport.h"
      71             : #endif
      72             : 
      73             : #ifdef MOZ_X11
      74             : #include "mozilla/X11Util.h"
      75             : using mozilla::DefaultXDisplay;
      76             : #endif
      77             : 
      78             : #ifdef XP_WIN
      79             : #include <wtypes.h>
      80             : #include <winuser.h>
      81             : #endif
      82             : 
      83             : #ifdef MOZ_WIDGET_ANDROID
      84             : #include "AndroidBridge.h"
      85             : #include "GLContext.h"
      86             : #endif
      87             : 
      88             : #include "mozilla/dom/TabChild.h"
      89             : 
      90             : #ifdef CreateEvent // Thank you MS.
      91             : #undef CreateEvent
      92             : #endif
      93             : 
      94             : static mozilla::LazyLogModule sPluginFrameLog("nsPluginFrame");
      95             : 
      96             : using namespace mozilla;
      97             : using namespace mozilla::gfx;
      98             : using namespace mozilla::layers;
      99             : 
     100             : class PluginBackgroundSink : public ReadbackSink {
     101             : public:
     102           0 :   PluginBackgroundSink(nsPluginFrame* aFrame, uint64_t aStartSequenceNumber)
     103           0 :     : mLastSequenceNumber(aStartSequenceNumber), mFrame(aFrame) {}
     104           0 :   ~PluginBackgroundSink() override
     105           0 :   {
     106           0 :     if (mFrame) {
     107           0 :       mFrame->mBackgroundSink = nullptr;
     108             :     }
     109           0 :   }
     110             : 
     111           0 :   void SetUnknown(uint64_t aSequenceNumber) override
     112             :   {
     113           0 :     if (!AcceptUpdate(aSequenceNumber))
     114           0 :       return;
     115           0 :     mFrame->mInstanceOwner->SetBackgroundUnknown();
     116             :   }
     117             : 
     118             :   already_AddRefed<DrawTarget>
     119           0 :       BeginUpdate(const nsIntRect& aRect, uint64_t aSequenceNumber) override
     120             :   {
     121           0 :     if (!AcceptUpdate(aSequenceNumber))
     122           0 :       return nullptr;
     123           0 :     return mFrame->mInstanceOwner->BeginUpdateBackground(aRect);
     124             :   }
     125             : 
     126           0 :   void EndUpdate(const nsIntRect& aRect) override
     127             :   {
     128           0 :     return mFrame->mInstanceOwner->EndUpdateBackground(aRect);
     129             :   }
     130             : 
     131           0 :   void Destroy() { mFrame = nullptr; }
     132             : 
     133             : protected:
     134           0 :   bool AcceptUpdate(uint64_t aSequenceNumber) {
     135           0 :     if (aSequenceNumber > mLastSequenceNumber && mFrame &&
     136           0 :         mFrame->mInstanceOwner) {
     137           0 :       mLastSequenceNumber = aSequenceNumber;
     138           0 :       return true;
     139             :     }
     140           0 :     return false;
     141             :   }
     142             : 
     143             :   uint64_t mLastSequenceNumber;
     144             :   nsPluginFrame* mFrame;
     145             : };
     146             : 
     147           0 : nsPluginFrame::nsPluginFrame(nsStyleContext* aContext)
     148             :   : nsFrame(aContext, kClassID)
     149             :   , mInstanceOwner(nullptr)
     150             :   , mOuterView(nullptr)
     151             :   , mInnerView(nullptr)
     152             :   , mBackgroundSink(nullptr)
     153           0 :   , mReflowCallbackPosted(false)
     154             : {
     155           0 :   MOZ_LOG(sPluginFrameLog, LogLevel::Debug,
     156             :          ("Created new nsPluginFrame %p\n", this));
     157           0 : }
     158             : 
     159           0 : nsPluginFrame::~nsPluginFrame()
     160             : {
     161           0 :   MOZ_LOG(sPluginFrameLog, LogLevel::Debug,
     162             :          ("nsPluginFrame %p deleted\n", this));
     163           0 : }
     164             : 
     165           0 : NS_QUERYFRAME_HEAD(nsPluginFrame)
     166           0 :   NS_QUERYFRAME_ENTRY(nsPluginFrame)
     167           0 :   NS_QUERYFRAME_ENTRY(nsIObjectFrame)
     168           0 : NS_QUERYFRAME_TAIL_INHERITING(nsFrame)
     169             : 
     170             : #ifdef ACCESSIBILITY
     171             : a11y::AccType
     172           0 : nsPluginFrame::AccessibleType()
     173             : {
     174           0 :   return a11y::ePluginType;
     175             : }
     176             : 
     177             : #ifdef XP_WIN
     178             : NS_IMETHODIMP nsPluginFrame::GetPluginPort(HWND *aPort)
     179             : {
     180             :   *aPort = (HWND) mInstanceOwner->GetPluginPort();
     181             :   return NS_OK;
     182             : }
     183             : #endif
     184             : #endif
     185             : 
     186             : void
     187           0 : nsPluginFrame::Init(nsIContent*       aContent,
     188             :                     nsContainerFrame* aParent,
     189             :                     nsIFrame*         aPrevInFlow)
     190             : {
     191           0 :   MOZ_LOG(sPluginFrameLog, LogLevel::Debug,
     192             :          ("Initializing nsPluginFrame %p for content %p\n", this, aContent));
     193             : 
     194           0 :   nsFrame::Init(aContent, aParent, aPrevInFlow);
     195           0 :   CreateView();
     196           0 : }
     197             : 
     198             : void
     199           0 : nsPluginFrame::DestroyFrom(nsIFrame* aDestructRoot)
     200             : {
     201           0 :   if (mReflowCallbackPosted) {
     202           0 :     PresContext()->PresShell()->CancelReflowCallback(this);
     203             :   }
     204             : 
     205             :   // Ensure our DidComposite observer is gone.
     206           0 :   mDidCompositeObserver = nullptr;
     207             : 
     208             :   // Tell content owner of the instance to disconnect its frame.
     209           0 :   nsCOMPtr<nsIObjectLoadingContent> objContent(do_QueryInterface(mContent));
     210           0 :   NS_ASSERTION(objContent, "Why not an object loading content?");
     211             : 
     212             :   // The content might not have a reference to the instance owner any longer in
     213             :   // the case of re-entry during instantiation or teardown, so make sure we're
     214             :   // dissociated.
     215           0 :   if (mInstanceOwner) {
     216           0 :     mInstanceOwner->SetFrame(nullptr);
     217             :   }
     218           0 :   objContent->HasNewFrame(nullptr);
     219             : 
     220           0 :   if (mBackgroundSink) {
     221           0 :     mBackgroundSink->Destroy();
     222             :   }
     223             : 
     224           0 :   nsFrame::DestroyFrom(aDestructRoot);
     225           0 : }
     226             : 
     227             : /* virtual */ void
     228           0 : nsPluginFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
     229             : {
     230           0 :   if (HasView()) {
     231           0 :     nsView* view = GetView();
     232           0 :     nsViewManager* vm = view->GetViewManager();
     233           0 :     if (vm) {
     234             :       nsViewVisibility visibility =
     235           0 :         IsHidden() ? nsViewVisibility_kHide : nsViewVisibility_kShow;
     236           0 :       vm->SetViewVisibility(view, visibility);
     237             :     }
     238             :   }
     239             : 
     240           0 :   nsFrame::DidSetStyleContext(aOldStyleContext);
     241           0 : }
     242             : 
     243             : #ifdef DEBUG_FRAME_DUMP
     244             : nsresult
     245           0 : nsPluginFrame::GetFrameName(nsAString& aResult) const
     246             : {
     247           0 :   return MakeFrameName(NS_LITERAL_STRING("PluginFrame"), aResult);
     248             : }
     249             : #endif
     250             : 
     251             : nsresult
     252           0 : nsPluginFrame::PrepForDrawing(nsIWidget *aWidget)
     253             : {
     254           0 :   mWidget = aWidget;
     255             : 
     256           0 :   nsView* view = GetView();
     257           0 :   NS_ASSERTION(view, "Object frames must have views");
     258           0 :   if (!view) {
     259           0 :     return NS_ERROR_FAILURE;
     260             :   }
     261             : 
     262           0 :   nsViewManager* viewMan = view->GetViewManager();
     263             :   // mark the view as hidden since we don't know the (x,y) until Paint
     264             :   // XXX is the above comment correct?
     265           0 :   viewMan->SetViewVisibility(view, nsViewVisibility_kHide);
     266             : 
     267             :   //this is ugly. it was ripped off from didreflow(). MMP
     268             :   // Position and size view relative to its parent, not relative to our
     269             :   // parent frame (our parent frame may not have a view).
     270             : 
     271             :   nsView* parentWithView;
     272           0 :   nsPoint origin;
     273           0 :   nsRect r(0, 0, mRect.width, mRect.height);
     274             : 
     275           0 :   GetOffsetFromView(origin, &parentWithView);
     276           0 :   viewMan->ResizeView(view, r);
     277           0 :   viewMan->MoveViewTo(view, origin.x, origin.y);
     278             : 
     279           0 :   nsPresContext* presContext = PresContext();
     280           0 :   nsRootPresContext* rpc = presContext->GetRootPresContext();
     281           0 :   if (!rpc) {
     282           0 :     return NS_ERROR_FAILURE;
     283             :   }
     284             : 
     285           0 :   if (mWidget) {
     286             :     // Disallow windowed plugins in popups
     287           0 :     nsIFrame* rootFrame = rpc->PresShell()->FrameManager()->GetRootFrame();
     288           0 :     nsIWidget* parentWidget = rootFrame->GetNearestWidget();
     289           0 :     if (!parentWidget || nsLayoutUtils::GetDisplayRootFrame(this) != rootFrame) {
     290           0 :       return NS_ERROR_FAILURE;
     291             :     }
     292             : 
     293             :     // We can already have mInnerView if our instance owner went away and then
     294             :     // came back. So clear the old one before creating a new one.
     295           0 :     if (mInnerView) {
     296           0 :       if (mInnerView->GetWidget()) {
     297             :         // The widget listener should have already been cleared by
     298             :         // SetInstanceOwner (with a null instance owner).
     299           0 :         MOZ_RELEASE_ASSERT(mInnerView->GetWidget()->GetWidgetListener() == nullptr);
     300             :       }
     301           0 :       mInnerView->Destroy();
     302           0 :       mInnerView = nullptr;
     303             :     }
     304           0 :     mInnerView = viewMan->CreateView(GetContentRectRelativeToSelf(), view);
     305           0 :     if (!mInnerView) {
     306           0 :       NS_ERROR("Could not create inner view");
     307           0 :       return NS_ERROR_OUT_OF_MEMORY;
     308             :     }
     309           0 :     viewMan->InsertChild(view, mInnerView, nullptr, true);
     310             : 
     311           0 :     mWidget->SetParent(parentWidget);
     312           0 :     mWidget->Enable(true);
     313           0 :     mWidget->Show(true);
     314             : 
     315             :     // Set the plugin window to have an empty clip region until we know
     316             :     // what our true position, size and clip region are. These
     317             :     // will be reset when nsRootPresContext computes our true
     318             :     // geometry. The plugin window does need to have a good size here, so
     319             :     // set the size explicitly to a reasonable guess.
     320           0 :     AutoTArray<nsIWidget::Configuration,1> configurations;
     321           0 :     nsIWidget::Configuration* configuration = configurations.AppendElement();
     322           0 :     nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
     323           0 :     configuration->mChild = mWidget;
     324           0 :     configuration->mBounds.width = NSAppUnitsToIntPixels(mRect.width, appUnitsPerDevPixel);
     325           0 :     configuration->mBounds.height = NSAppUnitsToIntPixels(mRect.height, appUnitsPerDevPixel);
     326           0 :     parentWidget->ConfigureChildren(configurations);
     327             : 
     328           0 :     mInnerView->AttachWidgetEventHandler(mWidget);
     329             : 
     330             : #ifdef XP_MACOSX
     331             :     // On Mac, we need to invalidate ourselves since even windowed
     332             :     // plugins are painted through Thebes and we need to ensure
     333             :     // the PaintedLayer containing the plugin is updated.
     334             :     if (parentWidget == GetNearestWidget()) {
     335             :       InvalidateFrame();
     336             :     }
     337             : #endif
     338             : 
     339           0 :     RegisterPluginForGeometryUpdates();
     340             : 
     341             :     // Here we set the background color for this widget because some plugins will use
     342             :     // the child window background color when painting. If it's not set, it may default to gray
     343             :     // Sometimes, a frame doesn't have a background color or is transparent. In this
     344             :     // case, walk up the frame tree until we do find a frame with a background color
     345           0 :     for (nsIFrame* frame = this; frame; frame = frame->GetParent()) {
     346             :       nscolor bgcolor = frame->
     347           0 :         GetVisitedDependentColor(&nsStyleBackground::mBackgroundColor);
     348           0 :       if (NS_GET_A(bgcolor) > 0) {  // make sure we got an actual color
     349           0 :         mWidget->SetBackgroundColor(bgcolor);
     350           0 :         break;
     351             :       }
     352             :     }
     353             :   } else {
     354             :     // Changing to windowless mode changes the NPWindow geometry.
     355           0 :     FixupWindow(GetContentRectRelativeToSelf().Size());
     356           0 :     RegisterPluginForGeometryUpdates();
     357             :   }
     358             : 
     359           0 :   if (!IsHidden()) {
     360           0 :     viewMan->SetViewVisibility(view, nsViewVisibility_kShow);
     361             :   }
     362             : 
     363             : #ifdef ACCESSIBILITY
     364           0 :   nsAccessibilityService* accService = nsIPresShell::AccService();
     365           0 :   if (accService) {
     366           0 :     accService->RecreateAccessible(PresContext()->PresShell(), mContent);
     367             :   }
     368             : #endif
     369             : 
     370           0 :   return NS_OK;
     371             : }
     372             : 
     373             : #define EMBED_DEF_WIDTH 240
     374             : #define EMBED_DEF_HEIGHT 200
     375             : 
     376             : /* virtual */ nscoord
     377           0 : nsPluginFrame::GetMinISize(gfxContext *aRenderingContext)
     378             : {
     379           0 :   nscoord result = 0;
     380             : 
     381           0 :   if (!IsHidden(false)) {
     382           0 :     if (mContent->IsAnyOfHTMLElements(nsGkAtoms::applet,
     383             :                                       nsGkAtoms::embed)) {
     384           0 :       bool vertical = GetWritingMode().IsVertical();
     385           0 :       result = nsPresContext::CSSPixelsToAppUnits(
     386             :         vertical ? EMBED_DEF_HEIGHT : EMBED_DEF_WIDTH);
     387             :     }
     388             :   }
     389             : 
     390           0 :   DISPLAY_MIN_WIDTH(this, result);
     391           0 :   return result;
     392             : }
     393             : 
     394             : /* virtual */ nscoord
     395           0 : nsPluginFrame::GetPrefISize(gfxContext *aRenderingContext)
     396             : {
     397           0 :   return nsPluginFrame::GetMinISize(aRenderingContext);
     398             : }
     399             : 
     400             : void
     401           0 : nsPluginFrame::GetWidgetConfiguration(nsTArray<nsIWidget::Configuration>* aConfigurations)
     402             : {
     403           0 :   if (!mWidget) {
     404           0 :     return;
     405             :   }
     406             : 
     407           0 :   if (!mWidget->GetParent()) {
     408             :     // Plugin widgets should not be toplevel except when they're out of the
     409             :     // document, in which case the plugin should not be registered for
     410             :     // geometry updates and this should not be called. But apparently we
     411             :     // have bugs where mWidget sometimes is toplevel here. Bail out.
     412           0 :     NS_ERROR("Plugin widgets registered for geometry updates should not be toplevel");
     413           0 :     return;
     414             :   }
     415             : 
     416           0 :   nsIWidget::Configuration* configuration = aConfigurations->AppendElement();
     417           0 :   configuration->mChild = mWidget;
     418           0 :   configuration->mBounds = mNextConfigurationBounds;
     419           0 :   configuration->mClipRegion = mNextConfigurationClipRegion;
     420             : #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
     421           0 :   if (XRE_IsContentProcess()) {
     422           0 :     configuration->mWindowID = (uintptr_t)mWidget->GetNativeData(NS_NATIVE_PLUGIN_PORT);
     423           0 :     configuration->mVisible = mWidget->IsVisible();
     424             : 
     425             :   }
     426             : #endif // defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
     427             : }
     428             : 
     429             : void
     430           0 : nsPluginFrame::GetDesiredSize(nsPresContext* aPresContext,
     431             :                               const ReflowInput& aReflowInput,
     432             :                               ReflowOutput& aMetrics)
     433             : {
     434             :   // By default, we have no area
     435           0 :   aMetrics.ClearSize();
     436             : 
     437           0 :   if (IsHidden(false)) {
     438           0 :     return;
     439             :   }
     440             : 
     441           0 :   aMetrics.Width() = aReflowInput.ComputedWidth();
     442           0 :   aMetrics.Height() = aReflowInput.ComputedHeight();
     443             : 
     444             :   // for EMBED and APPLET, default to 240x200 for compatibility
     445           0 :   if (mContent->IsAnyOfHTMLElements(nsGkAtoms::applet,
     446             :                                     nsGkAtoms::embed)) {
     447           0 :     if (aMetrics.Width() == NS_UNCONSTRAINEDSIZE) {
     448           0 :       aMetrics.Width() = clamped(nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_WIDTH),
     449           0 :                                aReflowInput.ComputedMinWidth(),
     450           0 :                                aReflowInput.ComputedMaxWidth());
     451             :     }
     452           0 :     if (aMetrics.Height() == NS_UNCONSTRAINEDSIZE) {
     453           0 :       aMetrics.Height() = clamped(nsPresContext::CSSPixelsToAppUnits(EMBED_DEF_HEIGHT),
     454           0 :                                 aReflowInput.ComputedMinHeight(),
     455           0 :                                 aReflowInput.ComputedMaxHeight());
     456             :     }
     457             : 
     458             : #if defined(MOZ_WIDGET_GTK)
     459             :     // We need to make sure that the size of the object frame does not
     460             :     // exceed the maximum size of X coordinates.  See bug #225357 for
     461             :     // more information.  In theory Gtk2 can handle large coordinates,
     462             :     // but underlying plugins can't.
     463           0 :     aMetrics.Height() = std::min(aPresContext->DevPixelsToAppUnits(INT16_MAX), aMetrics.Height());
     464           0 :     aMetrics.Width() = std::min(aPresContext->DevPixelsToAppUnits(INT16_MAX), aMetrics.Width());
     465             : #endif
     466             :   }
     467             : 
     468             :   // At this point, the width has an unconstrained value only if we have
     469             :   // nothing to go on (no width set, no information from the plugin, nothing).
     470             :   // Make up a number.
     471           0 :   if (aMetrics.Width() == NS_UNCONSTRAINEDSIZE) {
     472           0 :     aMetrics.Width() =
     473           0 :       (aReflowInput.ComputedMinWidth() != NS_UNCONSTRAINEDSIZE) ?
     474             :         aReflowInput.ComputedMinWidth() : 0;
     475             :   }
     476             : 
     477             :   // At this point, the height has an unconstrained value only in two cases:
     478             :   // a) We are in standards mode with percent heights and parent is auto-height
     479             :   // b) We have no height information at all.
     480             :   // In either case, we have to make up a number.
     481           0 :   if (aMetrics.Height() == NS_UNCONSTRAINEDSIZE) {
     482           0 :     aMetrics.Height() =
     483           0 :       (aReflowInput.ComputedMinHeight() != NS_UNCONSTRAINEDSIZE) ?
     484             :         aReflowInput.ComputedMinHeight() : 0;
     485             :   }
     486             : 
     487             :   // XXXbz don't add in the border and padding, because we screw up our
     488             :   // plugin's size and positioning if we do...  Eventually we _do_ want to
     489             :   // paint borders, though!  At that point, we will need to adjust the desired
     490             :   // size either here or in Reflow....  Further, we will need to fix Paint() to
     491             :   // call the superclass in all cases.
     492             : }
     493             : 
     494             : void
     495           0 : nsPluginFrame::Reflow(nsPresContext*           aPresContext,
     496             :                       ReflowOutput&     aMetrics,
     497             :                       const ReflowInput& aReflowInput,
     498             :                       nsReflowStatus&          aStatus)
     499             : {
     500           0 :   MarkInReflow();
     501           0 :   DO_GLOBAL_REFLOW_COUNT("nsPluginFrame");
     502           0 :   DISPLAY_REFLOW(aPresContext, this, aReflowInput, aMetrics, aStatus);
     503             : 
     504             :   // Get our desired size
     505           0 :   GetDesiredSize(aPresContext, aReflowInput, aMetrics);
     506           0 :   aMetrics.SetOverflowAreasToDesiredBounds();
     507           0 :   FinishAndStoreOverflow(&aMetrics);
     508             : 
     509             :   // delay plugin instantiation until all children have
     510             :   // arrived. Otherwise there may be PARAMs or other stuff that the
     511             :   // plugin needs to see that haven't arrived yet.
     512           0 :   if (!GetContent()->IsDoneAddingChildren()) {
     513           0 :     aStatus.Reset();
     514           0 :     return;
     515             :   }
     516             : 
     517             :   // if we are printing or print previewing, bail for now
     518           0 :   if (aPresContext->Medium() == nsGkAtoms::print) {
     519           0 :     aStatus.Reset();
     520           0 :     return;
     521             :   }
     522             : 
     523           0 :   nsRect r(0, 0, aMetrics.Width(), aMetrics.Height());
     524           0 :   r.Deflate(aReflowInput.ComputedPhysicalBorderPadding());
     525             : 
     526           0 :   if (mInnerView) {
     527           0 :     nsViewManager* vm = mInnerView->GetViewManager();
     528           0 :     vm->MoveViewTo(mInnerView, r.x, r.y);
     529           0 :     vm->ResizeView(mInnerView, nsRect(nsPoint(0, 0), r.Size()), true);
     530             :   }
     531             : 
     532           0 :   FixupWindow(r.Size());
     533           0 :   if (!mReflowCallbackPosted) {
     534           0 :     mReflowCallbackPosted = true;
     535           0 :     aPresContext->PresShell()->PostReflowCallback(this);
     536             :   }
     537             : 
     538           0 :   aStatus.Reset();
     539             : 
     540           0 :   NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics);
     541             : }
     542             : 
     543             : ///////////// nsIReflowCallback ///////////////
     544             : 
     545             : bool
     546           0 : nsPluginFrame::ReflowFinished()
     547             : {
     548           0 :   mReflowCallbackPosted = false;
     549           0 :   CallSetWindow();
     550           0 :   return true;
     551             : }
     552             : 
     553             : void
     554           0 : nsPluginFrame::ReflowCallbackCanceled()
     555             : {
     556           0 :   mReflowCallbackPosted = false;
     557           0 : }
     558             : 
     559             : void
     560           0 : nsPluginFrame::FixupWindow(const nsSize& aSize)
     561             : {
     562           0 :   nsPresContext* presContext = PresContext();
     563             : 
     564           0 :   if (!mInstanceOwner)
     565           0 :     return;
     566             : 
     567             :   NPWindow *window;
     568           0 :   mInstanceOwner->GetWindow(window);
     569             : 
     570           0 :   NS_ENSURE_TRUE_VOID(window);
     571             : 
     572           0 :   bool windowless = (window->type == NPWindowTypeDrawable);
     573             : 
     574           0 :   nsIntPoint origin = GetWindowOriginInPixels(windowless);
     575             : 
     576             :   // window must be in "display pixels"
     577             : #if defined(XP_MACOSX)
     578             :   // window must be in "display pixels"
     579             :   double scaleFactor = 1.0;
     580             :   if (NS_FAILED(mInstanceOwner->GetContentsScaleFactor(&scaleFactor))) {
     581             :     scaleFactor = 1.0;
     582             :   }
     583             :   int intScaleFactor = ceil(scaleFactor);
     584             :   window->x = origin.x / intScaleFactor;
     585             :   window->y = origin.y / intScaleFactor;
     586             :   window->width = presContext->AppUnitsToDevPixels(aSize.width) / intScaleFactor;
     587             :   window->height = presContext->AppUnitsToDevPixels(aSize.height) / intScaleFactor;
     588             : #else
     589           0 :   window->x = origin.x;
     590           0 :   window->y = origin.y;
     591           0 :   window->width = presContext->AppUnitsToDevPixels(aSize.width);
     592           0 :   window->height = presContext->AppUnitsToDevPixels(aSize.height);
     593             : #endif
     594             : 
     595             : #ifndef XP_MACOSX
     596           0 :   mInstanceOwner->UpdateWindowPositionAndClipRect(false);
     597             : #endif
     598             : 
     599           0 :   NotifyPluginReflowObservers();
     600             : }
     601             : 
     602             : nsresult
     603           0 : nsPluginFrame::CallSetWindow(bool aCheckIsHidden)
     604             : {
     605           0 :   NPWindow *win = nullptr;
     606             : 
     607           0 :   nsresult rv = NS_ERROR_FAILURE;
     608           0 :   RefPtr<nsNPAPIPluginInstance> pi;
     609           0 :   if (!mInstanceOwner ||
     610           0 :       NS_FAILED(rv = mInstanceOwner->GetInstance(getter_AddRefs(pi))) ||
     611           0 :       !pi ||
     612           0 :       NS_FAILED(rv = mInstanceOwner->GetWindow(win)) ||
     613           0 :       !win)
     614           0 :     return rv;
     615             : 
     616           0 :   nsPluginNativeWindow *window = (nsPluginNativeWindow *)win;
     617             : 
     618           0 :   if (aCheckIsHidden && IsHidden())
     619           0 :     return NS_ERROR_FAILURE;
     620             : 
     621             :   // Calling either nsPluginInstanceOwner::FixUpPluginWindow() (here,
     622             :   // on OS X) or SetWindow() (below, on all platforms) can destroy this
     623             :   // frame.  (FixUpPluginWindow() calls SetWindow()).  So grab a safe
     624             :   // reference to mInstanceOwner which we can use below, if needed.
     625           0 :   RefPtr<nsPluginInstanceOwner> instanceOwnerRef(mInstanceOwner);
     626             : 
     627             :   // refresh the plugin port as well
     628             : #ifdef XP_MACOSX
     629             :   mInstanceOwner->FixUpPluginWindow(nsPluginInstanceOwner::ePluginPaintEnable);
     630             :   // Bail now if our frame has been destroyed.
     631             :   if (!instanceOwnerRef->GetFrame()) {
     632             :     return NS_ERROR_FAILURE;
     633             :   }
     634             : #endif
     635           0 :   window->window = mInstanceOwner->GetPluginPort();
     636             : 
     637             :   // Adjust plugin dimensions according to pixel snap results
     638             :   // and reduce amount of SetWindow calls
     639           0 :   nsPresContext* presContext = PresContext();
     640           0 :   nsRootPresContext* rootPC = presContext->GetRootPresContext();
     641           0 :   if (!rootPC)
     642           0 :     return NS_ERROR_FAILURE;
     643           0 :   int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
     644           0 :   nsIFrame* rootFrame = rootPC->PresShell()->FrameManager()->GetRootFrame();
     645           0 :   nsRect bounds = GetContentRectRelativeToSelf() + GetOffsetToCrossDoc(rootFrame);
     646           0 :   nsIntRect intBounds = bounds.ToNearestPixels(appUnitsPerDevPixel);
     647             : 
     648             :   // In e10s, this returns the offset to the top level window, in non-e10s
     649             :   // it return 0,0.
     650           0 :   LayoutDeviceIntPoint intOffset = GetRemoteTabChromeOffset();
     651           0 :   intBounds.x += intOffset.x;
     652           0 :   intBounds.y += intOffset.y;
     653             : 
     654             : #if defined(XP_MACOSX)
     655             :   // window must be in "display pixels"
     656             :   double scaleFactor = 1.0;
     657             :   if (NS_FAILED(instanceOwnerRef->GetContentsScaleFactor(&scaleFactor))) {
     658             :     scaleFactor = 1.0;
     659             :   }
     660             : 
     661             :   size_t intScaleFactor = ceil(scaleFactor);
     662             :   window->x = intBounds.x / intScaleFactor;
     663             :   window->y = intBounds.y / intScaleFactor;
     664             :   window->width = intBounds.width / intScaleFactor;
     665             :   window->height = intBounds.height / intScaleFactor;
     666             : #else
     667           0 :   window->x = intBounds.x;
     668           0 :   window->y = intBounds.y;
     669           0 :   window->width = intBounds.width;
     670           0 :   window->height = intBounds.height;
     671             : #endif
     672             :   // BE CAREFUL: By the time we get here the PluginFrame is sometimes destroyed
     673             :   // and poisoned. If we reference local fields (implicit this deref),
     674             :   // we will crash.
     675           0 :   instanceOwnerRef->ResolutionMayHaveChanged();
     676             : 
     677             :   // This will call pi->SetWindow and take care of window subclassing
     678             :   // if needed, see bug 132759. Calling SetWindow can destroy this frame
     679             :   // so check for that before doing anything else with this frame's memory.
     680           0 :   if (instanceOwnerRef->UseAsyncRendering()) {
     681           0 :     rv = pi->AsyncSetWindow(window);
     682             :   }
     683             :   else {
     684           0 :     rv = window->CallSetWindow(pi);
     685             :   }
     686             : 
     687           0 :   instanceOwnerRef->ReleasePluginPort(window->window);
     688             : 
     689           0 :   return rv;
     690             : }
     691             : 
     692             : void
     693           0 : nsPluginFrame::RegisterPluginForGeometryUpdates()
     694             : {
     695           0 :   nsRootPresContext* rpc = PresContext()->GetRootPresContext();
     696           0 :   NS_ASSERTION(rpc, "We should have a root pres context!");
     697           0 :   if (mRootPresContextRegisteredWith == rpc || !rpc) {
     698             :     // Already registered with current root pres context,
     699             :     // or null root pres context...
     700           0 :     return;
     701             :   }
     702           0 :   if (mRootPresContextRegisteredWith && mRootPresContextRegisteredWith != rpc) {
     703             :     // Registered to some other root pres context. Unregister, and
     704             :     // re-register with our current one...
     705           0 :     UnregisterPluginForGeometryUpdates();
     706             :   }
     707           0 :   mRootPresContextRegisteredWith = rpc;
     708           0 :   mRootPresContextRegisteredWith->RegisterPluginForGeometryUpdates(mContent);
     709             : }
     710             : 
     711             : void
     712           0 : nsPluginFrame::UnregisterPluginForGeometryUpdates()
     713             : {
     714           0 :   if (!mRootPresContextRegisteredWith) {
     715             :     // Not registered...
     716           0 :     return;
     717             :   }
     718           0 :   mRootPresContextRegisteredWith->UnregisterPluginForGeometryUpdates(mContent);
     719           0 :   mRootPresContextRegisteredWith = nullptr;
     720             : }
     721             : 
     722             : void
     723           0 : nsPluginFrame::SetInstanceOwner(nsPluginInstanceOwner* aOwner)
     724             : {
     725             :   // The ownership model here is historically fuzzy. This should only be called
     726             :   // by nsPluginInstanceOwner when it is given a new frame, and
     727             :   // nsObjectLoadingContent should be arbitrating frame-ownership via its
     728             :   // HasNewFrame callback.
     729           0 :   mInstanceOwner = aOwner;
     730             : 
     731             :   // Reset the DidCompositeObserver since the owner changed.
     732           0 :   mDidCompositeObserver = nullptr;
     733             : 
     734           0 :   if (mInstanceOwner) {
     735           0 :     return;
     736             :   }
     737             : 
     738           0 :   UnregisterPluginForGeometryUpdates();
     739           0 :   if (mWidget && mInnerView) {
     740           0 :     mInnerView->DetachWidgetEventHandler(mWidget);
     741             :     // Make sure the plugin is hidden in case an update of plugin geometry
     742             :     // hasn't happened since this plugin became hidden.
     743           0 :     nsIWidget* parent = mWidget->GetParent();
     744           0 :     if (parent) {
     745           0 :       nsTArray<nsIWidget::Configuration> configurations;
     746           0 :       nsIWidget::Configuration* configuration = configurations.AppendElement();
     747           0 :       configuration->mChild = mWidget;
     748           0 :       parent->ConfigureChildren(configurations);
     749             : 
     750           0 :       mWidget->Show(false);
     751           0 :       mWidget->Enable(false);
     752           0 :       mWidget->SetParent(nullptr);
     753             :     }
     754             :   }
     755             : }
     756             : 
     757             : bool
     758           0 : nsPluginFrame::IsFocusable(int32_t *aTabIndex, bool aWithMouse)
     759             : {
     760           0 :   if (aTabIndex)
     761           0 :     *aTabIndex = -1;
     762           0 :   return nsFrame::IsFocusable(aTabIndex, aWithMouse);
     763             : }
     764             : 
     765             : bool
     766           0 : nsPluginFrame::IsHidden(bool aCheckVisibilityStyle) const
     767             : {
     768           0 :   if (aCheckVisibilityStyle) {
     769           0 :     if (!StyleVisibility()->IsVisibleOrCollapsed())
     770           0 :       return true;
     771             :   }
     772             : 
     773             :   // only <embed> tags support the HIDDEN attribute
     774           0 :   if (mContent->IsHTMLElement(nsGkAtoms::embed)) {
     775             :     // Yes, these are really the kooky ways that you could tell 4.x
     776             :     // not to hide the <embed> once you'd put the 'hidden' attribute
     777             :     // on the tag...
     778             : 
     779             :     // HIDDEN w/ no attributes gets translated as we are hidden for
     780             :     // compatibility w/ 4.x and IE so we don't create a non-painting
     781             :     // widget in layout. See bug 188959.
     782           0 :     nsAutoString hidden;
     783           0 :     if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::hidden, hidden) &&
     784           0 :        (hidden.IsEmpty() ||
     785           0 :         (!hidden.LowerCaseEqualsLiteral("false") &&
     786           0 :          !hidden.LowerCaseEqualsLiteral("no") &&
     787           0 :          !hidden.LowerCaseEqualsLiteral("off")))) {
     788           0 :       return true;
     789             :     }
     790             :   }
     791             : 
     792           0 :   return false;
     793             : }
     794             : 
     795             : mozilla::LayoutDeviceIntPoint
     796           0 : nsPluginFrame::GetRemoteTabChromeOffset()
     797             : {
     798           0 :   LayoutDeviceIntPoint offset;
     799           0 :   if (XRE_IsContentProcess()) {
     800           0 :     if (nsPIDOMWindowOuter* window = GetContent()->OwnerDoc()->GetWindow()) {
     801           0 :       if (nsCOMPtr<nsPIDOMWindowOuter> topWindow = window->GetTop()) {
     802           0 :         dom::TabChild* tc = dom::TabChild::GetFrom(topWindow);
     803           0 :         if (tc) {
     804           0 :           offset += tc->GetChromeDisplacement();
     805             :         }
     806             :       }
     807             :     }
     808             :   }
     809           0 :   return offset;
     810             : }
     811             : 
     812             : nsIntPoint
     813           0 : nsPluginFrame::GetWindowOriginInPixels(bool aWindowless)
     814             : {
     815             :   nsView * parentWithView;
     816           0 :   nsPoint origin(0,0);
     817             : 
     818           0 :   GetOffsetFromView(origin, &parentWithView);
     819             : 
     820             :   // if it's windowless, let's make sure we have our origin set right
     821             :   // it may need to be corrected, like after scrolling
     822           0 :   if (aWindowless && parentWithView) {
     823           0 :     nsPoint offsetToWidget;
     824           0 :     parentWithView->GetNearestWidget(&offsetToWidget);
     825           0 :     origin += offsetToWidget;
     826             :   }
     827           0 :   origin += GetContentRectRelativeToSelf().TopLeft();
     828             : 
     829             :   nsIntPoint pt(PresContext()->AppUnitsToDevPixels(origin.x),
     830           0 :                 PresContext()->AppUnitsToDevPixels(origin.y));
     831             : 
     832             :   // If we're in the content process offsetToWidget is tied to the top level
     833             :   // widget we can access in the child process, which is the tab. We need the
     834             :   // offset all the way up to the top level native window here. (If this is
     835             :   // non-e10s this routine will return 0,0.)
     836           0 :   if (aWindowless) {
     837           0 :     mozilla::LayoutDeviceIntPoint lpt = GetRemoteTabChromeOffset();
     838           0 :     pt += nsIntPoint(lpt.x, lpt.y);
     839             :   }
     840             : 
     841           0 :   return pt;
     842             : }
     843             : 
     844             : void
     845           0 : nsPluginFrame::DidReflow(nsPresContext*            aPresContext,
     846             :                          const ReflowInput*  aReflowInput,
     847             :                          nsDidReflowStatus         aStatus)
     848             : {
     849             :   // Do this check before calling the superclass, as that clears
     850             :   // NS_FRAME_FIRST_REFLOW
     851           0 :   if (aStatus == nsDidReflowStatus::FINISHED &&
     852           0 :       (GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
     853           0 :     nsCOMPtr<nsIObjectLoadingContent> objContent(do_QueryInterface(mContent));
     854           0 :     NS_ASSERTION(objContent, "Why not an object loading content?");
     855           0 :     objContent->HasNewFrame(this);
     856             :   }
     857             : 
     858           0 :   nsFrame::DidReflow(aPresContext, aReflowInput, aStatus);
     859             : 
     860             :   // The view is created hidden; once we have reflowed it and it has been
     861             :   // positioned then we show it.
     862           0 :   if (aStatus != nsDidReflowStatus::FINISHED)
     863           0 :     return;
     864             : 
     865           0 :   if (HasView()) {
     866           0 :     nsView* view = GetView();
     867           0 :     nsViewManager* vm = view->GetViewManager();
     868           0 :     if (vm)
     869           0 :       vm->SetViewVisibility(view, IsHidden() ? nsViewVisibility_kHide : nsViewVisibility_kShow);
     870             :   }
     871             : }
     872             : 
     873             : /* static */ void
     874           0 : nsPluginFrame::PaintPrintPlugin(nsIFrame* aFrame, gfxContext* aCtx,
     875             :                                 const nsRect& aDirtyRect, nsPoint aPt)
     876             : {
     877             :   // Translate the context:
     878           0 :   nsPoint pt = aPt + aFrame->GetContentRectRelativeToSelf().TopLeft();
     879             :   gfxPoint devPixelPt =
     880           0 :     nsLayoutUtils::PointToGfxPoint(pt, aFrame->PresContext()->AppUnitsPerDevPixel());
     881             : 
     882           0 :   gfxContextMatrixAutoSaveRestore autoSR(aCtx);
     883           0 :   aCtx->SetMatrix(aCtx->CurrentMatrix().PreTranslate(devPixelPt));
     884             : 
     885             :   // FIXME - Bug 385435: Doesn't aDirtyRect need translating too?
     886             : 
     887           0 :   static_cast<nsPluginFrame*>(aFrame)->PrintPlugin(*aCtx, aDirtyRect);
     888           0 : }
     889             : 
     890             : /**
     891             :  * nsDisplayPluginReadback creates an active ReadbackLayer. The ReadbackLayer
     892             :  * obtains from the compositor the contents of the window underneath
     893             :  * the ReadbackLayer, which we then use as an opaque buffer for plugins to
     894             :  * asynchronously draw onto.
     895             :  */
     896             : class nsDisplayPluginReadback : public nsDisplayItem {
     897             : public:
     898           0 :   nsDisplayPluginReadback(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
     899           0 :     : nsDisplayItem(aBuilder, aFrame)
     900             :   {
     901           0 :     MOZ_COUNT_CTOR(nsDisplayPluginReadback);
     902           0 :   }
     903             : #ifdef NS_BUILD_REFCNT_LOGGING
     904           0 :   ~nsDisplayPluginReadback() override {
     905           0 :     MOZ_COUNT_DTOR(nsDisplayPluginReadback);
     906           0 :   }
     907             : #endif
     908             : 
     909             :   nsRect GetBounds(nsDisplayListBuilder* aBuilder,
     910             :                            bool* aSnap) override;
     911             : 
     912           0 :   NS_DISPLAY_DECL_NAME("PluginReadback", TYPE_PLUGIN_READBACK)
     913             : 
     914           0 :   already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
     915             :                                              LayerManager* aManager,
     916             :                                              const ContainerLayerParameters& aContainerParameters) override
     917             :   {
     918           0 :     return static_cast<nsPluginFrame*>(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters);
     919             :   }
     920             : 
     921           0 :   LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
     922             :                                    LayerManager* aManager,
     923             :                                    const ContainerLayerParameters& aParameters) override
     924             :   {
     925           0 :     return LAYER_ACTIVE;
     926             :   }
     927             : };
     928             : 
     929             : static nsRect
     930           0 : GetDisplayItemBounds(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, nsIFrame* aFrame)
     931             : {
     932             :   // XXX For slightly more accurate region computations we should pixel-snap this
     933           0 :   return aFrame->GetContentRectRelativeToSelf() + aItem->ToReferenceFrame();
     934             : }
     935             : 
     936             : nsRect
     937           0 : nsDisplayPluginReadback::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
     938             : {
     939           0 :   *aSnap = false;
     940           0 :   return GetDisplayItemBounds(aBuilder, this, mFrame);
     941             : }
     942             : 
     943             : #ifdef MOZ_WIDGET_ANDROID
     944             : 
     945             : class nsDisplayPluginVideo : public nsDisplayItem {
     946             : public:
     947             :   nsDisplayPluginVideo(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsNPAPIPluginInstance::VideoInfo* aVideoInfo)
     948             :     : nsDisplayItem(aBuilder, aFrame), mVideoInfo(aVideoInfo)
     949             :   {
     950             :     MOZ_COUNT_CTOR(nsDisplayPluginVideo);
     951             :   }
     952             : #ifdef NS_BUILD_REFCNT_LOGGING
     953             :   virtual ~nsDisplayPluginVideo() {
     954             :     MOZ_COUNT_DTOR(nsDisplayPluginVideo);
     955             :   }
     956             : #endif
     957             : 
     958             :   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
     959             :                            bool* aSnap) override;
     960             : 
     961             :   NS_DISPLAY_DECL_NAME("PluginVideo", TYPE_PLUGIN_VIDEO)
     962             : 
     963             :   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
     964             :                                              LayerManager* aManager,
     965             :                                              const ContainerLayerParameters& aContainerParameters) override
     966             :   {
     967             :     return static_cast<nsPluginFrame*>(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters);
     968             :   }
     969             : 
     970             :   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
     971             :                                    LayerManager* aManager,
     972             :                                    const ContainerLayerParameters& aParameters) override
     973             :   {
     974             :     return LAYER_ACTIVE;
     975             :   }
     976             : 
     977             :   nsNPAPIPluginInstance::VideoInfo* VideoInfo() { return mVideoInfo; }
     978             : 
     979             : private:
     980             :   nsNPAPIPluginInstance::VideoInfo* mVideoInfo;
     981             : };
     982             : 
     983             : nsRect
     984             : nsDisplayPluginVideo::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
     985             : {
     986             :   *aSnap = false;
     987             :   return GetDisplayItemBounds(aBuilder, this, mFrame);
     988             : }
     989             : 
     990             : #endif
     991             : 
     992             : nsRect
     993           0 : nsDisplayPlugin::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
     994             : {
     995           0 :   *aSnap = true;
     996           0 :   return GetDisplayItemBounds(aBuilder, this, mFrame);
     997             : }
     998             : 
     999             : void
    1000           0 : nsDisplayPlugin::Paint(nsDisplayListBuilder* aBuilder,
    1001             :                        gfxContext* aCtx)
    1002             : {
    1003           0 :   nsPluginFrame* f = static_cast<nsPluginFrame*>(mFrame);
    1004             :   bool snap;
    1005           0 :   f->PaintPlugin(aBuilder, *aCtx, mVisibleRect, GetBounds(aBuilder, &snap));
    1006           0 : }
    1007             : 
    1008             : static nsRect
    1009           0 : GetClippedBoundsIncludingAllScrollClips(nsDisplayItem* aItem,
    1010             :                                         nsDisplayListBuilder* aBuilder)
    1011             : {
    1012           0 :   nsRect r = aItem->GetClippedBounds(aBuilder);
    1013           0 :   for (auto* sc = aItem->GetClipChain(); sc; sc = sc->mParent) {
    1014           0 :     r = sc->mClip.ApplyNonRoundedIntersection(r);
    1015             :   }
    1016           0 :   return r;
    1017             : }
    1018             : 
    1019             : bool
    1020           0 : nsDisplayPlugin::ComputeVisibility(nsDisplayListBuilder* aBuilder,
    1021             :                                    nsRegion* aVisibleRegion)
    1022             : {
    1023           0 :   if (aBuilder->IsForPluginGeometry()) {
    1024           0 :     nsPluginFrame* f = static_cast<nsPluginFrame*>(mFrame);
    1025           0 :     if (!aBuilder->IsInTransform() || f->IsPaintedByGecko()) {
    1026             :       // Since transforms induce reference frames, we don't need to worry
    1027             :       // about this method fluffing out due to non-rectilinear transforms.
    1028             :       nsRect rAncestor = nsLayoutUtils::TransformFrameRectToAncestor(f,
    1029           0 :           f->GetContentRectRelativeToSelf(), ReferenceFrame());
    1030             :       nscoord appUnitsPerDevPixel =
    1031           0 :         ReferenceFrame()->PresContext()->AppUnitsPerDevPixel();
    1032             :       f->mNextConfigurationBounds = LayoutDeviceIntRect::FromUnknownRect(
    1033           0 :         rAncestor.ToNearestPixels(appUnitsPerDevPixel));
    1034             : 
    1035           0 :       nsRegion visibleRegion;
    1036             :       // Apply all scroll clips when computing the clipped bounds of this item.
    1037             :       // We hide windowed plugins during APZ scrolling, so there never is an
    1038             :       // async transform that we need to take into account when clipping.
    1039           0 :       visibleRegion.And(*aVisibleRegion, GetClippedBoundsIncludingAllScrollClips(this, aBuilder));
    1040             :       // Make visibleRegion relative to f
    1041           0 :       visibleRegion.MoveBy(-ToReferenceFrame());
    1042             : 
    1043           0 :       f->mNextConfigurationClipRegion.Clear();
    1044           0 :       for (auto iter = visibleRegion.RectIter(); !iter.Done(); iter.Next()) {
    1045             :         nsRect rAncestor =
    1046           0 :           nsLayoutUtils::TransformFrameRectToAncestor(f, iter.Get(), ReferenceFrame());
    1047             :         LayoutDeviceIntRect rPixels =
    1048           0 :           LayoutDeviceIntRect::FromUnknownRect(rAncestor.ToNearestPixels(appUnitsPerDevPixel)) -
    1049           0 :           f->mNextConfigurationBounds.TopLeft();
    1050           0 :         if (!rPixels.IsEmpty()) {
    1051           0 :           f->mNextConfigurationClipRegion.AppendElement(rPixels);
    1052             :         }
    1053             :       }
    1054             :     }
    1055             : 
    1056           0 :     if (f->mInnerView) {
    1057             :       // This should produce basically the same rectangle (but not relative
    1058             :       // to the root frame). We only call this here for the side-effect of
    1059             :       // setting mViewToWidgetOffset on the view.
    1060           0 :       f->mInnerView->CalcWidgetBounds(eWindowType_plugin);
    1061             :     }
    1062             :   }
    1063             : 
    1064           0 :   return nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion);
    1065             : }
    1066             : 
    1067             : nsRegion
    1068           0 : nsDisplayPlugin::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
    1069             :                                  bool* aSnap)
    1070             : {
    1071           0 :   *aSnap = false;
    1072           0 :   nsRegion result;
    1073           0 :   nsPluginFrame* f = static_cast<nsPluginFrame*>(mFrame);
    1074           0 :   if (!aBuilder->IsForPluginGeometry()) {
    1075           0 :     nsIWidget* widget = f->GetWidget();
    1076           0 :     if (widget) {
    1077             :       // Be conservative and treat plugins with widgets as not opaque,
    1078             :       // because that's simple and we might need the content under the widget
    1079             :       // if the widget is unexpectedly clipped away. (As can happen when
    1080             :       // chrome content over a plugin forces us to clip out the plugin for
    1081             :       // security reasons.)
    1082             :       // We shouldn't be repainting the content under plugins much anyway
    1083             :       // since there generally shouldn't be anything to invalidate or paint
    1084             :       // in PaintedLayers there.
    1085           0 :           return result;
    1086             :     }
    1087             :   }
    1088             : 
    1089           0 :   if (f->IsOpaque()) {
    1090           0 :     nsRect bounds = GetBounds(aBuilder, aSnap);
    1091           0 :     if (aBuilder->IsForPluginGeometry() ||
    1092           0 :         (f->GetPaintedRect(this) + ToReferenceFrame()).Contains(bounds)) {
    1093             :       // We can treat this as opaque
    1094           0 :       result = bounds;
    1095             :     }
    1096             :   }
    1097             : 
    1098           0 :   return result;
    1099             : }
    1100             : 
    1101             : nsresult
    1102           0 : nsPluginFrame::PluginEventNotifier::Run() {
    1103             :   nsCOMPtr<nsIObserverService> obsSvc =
    1104           0 :     mozilla::services::GetObserverService();
    1105           0 :   obsSvc->NotifyObservers(nullptr, "plugin-changed-event", mEventType.get());
    1106           0 :   return NS_OK;
    1107             : }
    1108             : 
    1109             : void
    1110           0 : nsPluginFrame::NotifyPluginReflowObservers()
    1111             : {
    1112           0 :   nsContentUtils::AddScriptRunner(new PluginEventNotifier(NS_LITERAL_STRING("reflow")));
    1113           0 : }
    1114             : 
    1115             : void
    1116           0 : nsPluginFrame::DidSetWidgetGeometry()
    1117             : {
    1118             : #if defined(XP_MACOSX)
    1119             :   if (mInstanceOwner && !IsHidden()) {
    1120             :     mInstanceOwner->FixUpPluginWindow(nsPluginInstanceOwner::ePluginPaintEnable);
    1121             :   }
    1122             : #else
    1123           0 :   if (!mWidget && mInstanceOwner) {
    1124             :     // UpdateWindowVisibility will notify the plugin of position changes
    1125             :     // by updating the NPWindow and calling NPP_SetWindow/AsyncSetWindow.
    1126             :     // We treat windowless plugins inside popups as always visible, since
    1127             :     // plugins inside popups don't get valid mNextConfigurationBounds
    1128             :     // set up.
    1129           0 :     mInstanceOwner->UpdateWindowVisibility(
    1130           0 :       nsLayoutUtils::IsPopup(nsLayoutUtils::GetDisplayRootFrame(this)) ||
    1131           0 :       !mNextConfigurationBounds.IsEmpty());
    1132             :   }
    1133             : #endif
    1134           0 : }
    1135             : 
    1136             : bool
    1137           0 : nsPluginFrame::IsOpaque() const
    1138             : {
    1139             : #if defined(XP_MACOSX)
    1140             :   return false;
    1141             : #elif defined(MOZ_WIDGET_ANDROID)
    1142             :   // We don't know, so just assume transparent
    1143             :   return false;
    1144             : #else
    1145             : 
    1146           0 :   if (mInstanceOwner && mInstanceOwner->UseAsyncRendering()) {
    1147           0 :     return false;
    1148             :   }
    1149           0 :   return !IsTransparentMode();
    1150             : #endif
    1151             : }
    1152             : 
    1153             : bool
    1154           0 : nsPluginFrame::IsTransparentMode() const
    1155             : {
    1156             : #if defined(XP_MACOSX)
    1157             :   return false;
    1158             : #else
    1159           0 :   if (!mInstanceOwner)
    1160           0 :     return false;
    1161             : 
    1162           0 :   NPWindow *window = nullptr;
    1163           0 :   mInstanceOwner->GetWindow(window);
    1164           0 :   if (!window) {
    1165           0 :     return false;
    1166             :   }
    1167             : 
    1168           0 :   if (window->type != NPWindowTypeDrawable)
    1169           0 :     return false;
    1170             : 
    1171             :   nsresult rv;
    1172           0 :   RefPtr<nsNPAPIPluginInstance> pi;
    1173           0 :   rv = mInstanceOwner->GetInstance(getter_AddRefs(pi));
    1174           0 :   if (NS_FAILED(rv) || !pi)
    1175           0 :     return false;
    1176             : 
    1177           0 :   bool transparent = false;
    1178           0 :   pi->IsTransparent(&transparent);
    1179           0 :   return transparent;
    1180             : #endif
    1181             : }
    1182             : 
    1183             : void
    1184           0 : nsPluginFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
    1185             :                                 const nsRect&           aDirtyRect,
    1186             :                                 const nsDisplayListSet& aLists)
    1187             : {
    1188             :   // XXX why are we painting collapsed object frames?
    1189           0 :   if (!IsVisibleOrCollapsedForPainting(aBuilder))
    1190           0 :     return;
    1191             : 
    1192           0 :   DisplayBorderBackgroundOutline(aBuilder, aLists);
    1193             : 
    1194           0 :   nsPresContext::nsPresContextType type = PresContext()->Type();
    1195             : 
    1196             :   // If we are painting in Print Preview do nothing....
    1197           0 :   if (type == nsPresContext::eContext_PrintPreview)
    1198           0 :     return;
    1199             : 
    1200           0 :   DO_GLOBAL_REFLOW_COUNT_DSP("nsPluginFrame");
    1201             : 
    1202             : #ifndef XP_MACOSX
    1203           0 :   if (mWidget && aBuilder->IsInTransform()) {
    1204             :     // Windowed plugins should not be rendered inside a transform.
    1205           0 :     return;
    1206             :   }
    1207             : #endif
    1208             : 
    1209           0 :   if (aBuilder->IsForPainting() && mInstanceOwner) {
    1210             :     // Update plugin frame for both content scaling and full zoom changes.
    1211           0 :     mInstanceOwner->ResolutionMayHaveChanged();
    1212             : #ifdef XP_MACOSX
    1213             :     mInstanceOwner->WindowFocusMayHaveChanged();
    1214             : #endif
    1215           0 :     if (mInstanceOwner->UseAsyncRendering()) {
    1216           0 :       NPWindow* window = nullptr;
    1217           0 :       mInstanceOwner->GetWindow(window);
    1218           0 :       bool isVisible = window && window->width > 0 && window->height > 0;
    1219           0 :       if (isVisible && aBuilder->ShouldSyncDecodeImages()) {
    1220             : #ifndef XP_MACOSX
    1221           0 :         mInstanceOwner->UpdateWindowVisibility(true);
    1222             : #endif
    1223             :       }
    1224             : 
    1225           0 :       mInstanceOwner->NotifyPaintWaiter(aBuilder);
    1226             :     }
    1227             :   }
    1228             : 
    1229             :   DisplayListClipState::AutoClipContainingBlockDescendantsToContentBox
    1230           0 :     clip(aBuilder, this);
    1231             : 
    1232             :   // determine if we are printing
    1233           0 :   if (type == nsPresContext::eContext_Print) {
    1234           0 :     aLists.Content()->AppendNewToTop(new (aBuilder)
    1235             :       nsDisplayGeneric(aBuilder, this, PaintPrintPlugin, "PrintPlugin",
    1236           0 :                        nsDisplayItem::TYPE_PRINT_PLUGIN));
    1237             :   } else {
    1238           0 :     LayerState state = GetLayerState(aBuilder, nullptr);
    1239           0 :     if (state == LAYER_INACTIVE &&
    1240           0 :         nsDisplayItem::ForceActiveLayers()) {
    1241           0 :       state = LAYER_ACTIVE;
    1242             :     }
    1243             :     // We don't need this on Android, and it just confuses things
    1244             : #if !MOZ_WIDGET_ANDROID
    1245           0 :     if (aBuilder->IsPaintingToWindow() &&
    1246           0 :         state == LAYER_ACTIVE &&
    1247           0 :         IsTransparentMode()) {
    1248           0 :       aLists.Content()->AppendNewToTop(new (aBuilder)
    1249           0 :         nsDisplayPluginReadback(aBuilder, this));
    1250             :     }
    1251             : #endif
    1252             : 
    1253             : #if MOZ_WIDGET_ANDROID
    1254             :     if (aBuilder->IsPaintingToWindow() &&
    1255             :         state == LAYER_ACTIVE) {
    1256             : 
    1257             :       nsTArray<nsNPAPIPluginInstance::VideoInfo*> videos;
    1258             :       mInstanceOwner->GetVideos(videos);
    1259             : 
    1260             :       for (uint32_t i = 0; i < videos.Length(); i++) {
    1261             :         aLists.Content()->AppendNewToTop(new (aBuilder)
    1262             :           nsDisplayPluginVideo(aBuilder, this, videos[i]));
    1263             :       }
    1264             :     }
    1265             : #endif
    1266             : 
    1267           0 :     aLists.Content()->AppendNewToTop(new (aBuilder)
    1268           0 :       nsDisplayPlugin(aBuilder, this));
    1269             :   }
    1270             : }
    1271             : 
    1272             : void
    1273           0 : nsPluginFrame::PrintPlugin(gfxContext& aRenderingContext,
    1274             :                            const nsRect& aDirtyRect)
    1275             : {
    1276           0 :   nsCOMPtr<nsIObjectLoadingContent> obj(do_QueryInterface(mContent));
    1277           0 :   if (!obj)
    1278           0 :     return;
    1279             : 
    1280           0 :   nsIFrame* frame = nullptr;
    1281           0 :   obj->GetPrintFrame(&frame);
    1282           0 :   if (!frame)
    1283           0 :     return;
    1284             : 
    1285           0 :   nsPresContext* presContext = PresContext();
    1286             :   // make sure this is REALLY an nsIObjectFrame
    1287             :   // we may need to go through the children to get it
    1288           0 :   nsIObjectFrame* objectFrame = do_QueryFrame(frame);
    1289           0 :   if (!objectFrame)
    1290           0 :     objectFrame = GetNextObjectFrame(presContext,frame);
    1291           0 :   if (!objectFrame)
    1292           0 :     return;
    1293             : 
    1294             :   // finally we can get our plugin instance
    1295           0 :   RefPtr<nsNPAPIPluginInstance> pi;
    1296           0 :   if (NS_FAILED(objectFrame->GetPluginInstance(getter_AddRefs(pi))) || !pi)
    1297           0 :     return;
    1298             : 
    1299             :   // now we need to setup the correct location for printing
    1300             :   NPWindow window;
    1301           0 :   window.window = nullptr;
    1302             : 
    1303             :   // prepare embedded mode printing struct
    1304             :   NPPrint npprint;
    1305           0 :   npprint.mode = NP_EMBED;
    1306             : 
    1307             :   // we need to find out if we are windowless or not
    1308           0 :   bool windowless = false;
    1309           0 :   pi->IsWindowless(&windowless);
    1310           0 :   window.type = windowless ? NPWindowTypeDrawable : NPWindowTypeWindow;
    1311             : 
    1312           0 :   window.clipRect.bottom = 0; window.clipRect.top = 0;
    1313           0 :   window.clipRect.left = 0; window.clipRect.right = 0;
    1314             : 
    1315             : // platform specific printing code
    1316             : #if defined(XP_UNIX) || defined(XP_MACOSX)
    1317             :   // Doesn't work in a thebes world, or on OS X.
    1318             :   (void)window;
    1319             :   (void)npprint;
    1320             : #elif defined(XP_WIN)
    1321             : 
    1322             :   /* On Windows, we use the win32 printing surface to print.  This, in
    1323             :    * turn, uses the Cairo paginated surface, which in turn uses the
    1324             :    * meta surface to record all operations and then play them back.
    1325             :    * This doesn't work too well for plugins, because if plugins render
    1326             :    * directly into the DC, the meta surface won't have any knowledge
    1327             :    * of them, and so at the end when it actually does the replay step,
    1328             :    * it'll fill the background with white and draw over whatever was
    1329             :    * rendered before.
    1330             :    *
    1331             :    * So, to avoid this, we use PushGroup, which creates a new windows
    1332             :    * surface, the plugin renders to that, and then we use normal
    1333             :    * cairo methods to composite that in such that it's recorded using the
    1334             :    * meta surface.
    1335             :    */
    1336             : 
    1337             :   /* we'll already be translated into the right spot by gfxWindowsNativeDrawing */
    1338             :   nsSize contentSize = GetContentRectRelativeToSelf().Size();
    1339             :   window.x = 0;
    1340             :   window.y = 0;
    1341             :   window.width = presContext->AppUnitsToDevPixels(contentSize.width);
    1342             :   window.height = presContext->AppUnitsToDevPixels(contentSize.height);
    1343             : 
    1344             :   aRenderingContext.Save();
    1345             : 
    1346             :   /* Make sure plugins don't do any damage outside of where they're supposed to */
    1347             :   aRenderingContext.NewPath();
    1348             :   gfxRect r(window.x, window.y, window.width, window.height);
    1349             :   aRenderingContext.Rectangle(r);
    1350             :   aRenderingContext.Clip();
    1351             : 
    1352             :   gfxWindowsNativeDrawing nativeDraw(&aRenderingContext, r);
    1353             :   do {
    1354             :     HDC dc = nativeDraw.BeginNativeDrawing();
    1355             :     if (!dc)
    1356             :       return;
    1357             : 
    1358             :     // XXX don't we need to call nativeDraw.TransformToNativeRect here?
    1359             :     npprint.print.embedPrint.platformPrint = dc;
    1360             :     npprint.print.embedPrint.window = window;
    1361             :     // send off print info to plugin
    1362             :     pi->Print(&npprint);
    1363             : 
    1364             :     nativeDraw.EndNativeDrawing();
    1365             :   } while (nativeDraw.ShouldRenderAgain());
    1366             :   nativeDraw.PaintToContext();
    1367             : 
    1368             :   aRenderingContext.Restore();
    1369             : #endif
    1370             : 
    1371             :   // XXX Nav 4.x always sent a SetWindow call after print. Should we do the same?
    1372             :   // XXX Calling DidReflow here makes no sense!!!
    1373           0 :   nsDidReflowStatus status = nsDidReflowStatus::FINISHED; // should we use a special status?
    1374           0 :   frame->DidReflow(presContext,
    1375           0 :                    nullptr, status);  // DidReflow will take care of it
    1376             : }
    1377             : 
    1378             : nsRect
    1379           0 : nsPluginFrame::GetPaintedRect(nsDisplayPlugin* aItem)
    1380             : {
    1381           0 :   if (!mInstanceOwner)
    1382           0 :     return nsRect();
    1383           0 :   nsRect r = GetContentRectRelativeToSelf();
    1384           0 :   if (!mInstanceOwner->UseAsyncRendering())
    1385           0 :     return r;
    1386             : 
    1387           0 :   nsIntSize size = mInstanceOwner->GetCurrentImageSize();
    1388           0 :   nsPresContext* pc = PresContext();
    1389           0 :   r.IntersectRect(r, nsRect(0, 0, pc->DevPixelsToAppUnits(size.width),
    1390           0 :                                   pc->DevPixelsToAppUnits(size.height)));
    1391           0 :   return r;
    1392             : }
    1393             : 
    1394             : LayerState
    1395           0 : nsPluginFrame::GetLayerState(nsDisplayListBuilder* aBuilder,
    1396             :                              LayerManager* aManager)
    1397             : {
    1398           0 :   if (!mInstanceOwner)
    1399           0 :     return LAYER_NONE;
    1400             : 
    1401             : #ifdef MOZ_WIDGET_ANDROID
    1402             :   // We always want a layer on Honeycomb and later
    1403             :   return LAYER_ACTIVE;
    1404             : #else
    1405           0 :   if (mInstanceOwner->NeedsScrollImageLayer()) {
    1406           0 :     return LAYER_ACTIVE;
    1407             :   }
    1408             : 
    1409           0 :   if (!mInstanceOwner->UseAsyncRendering()) {
    1410           0 :     return LAYER_NONE;
    1411             :   }
    1412             : 
    1413           0 :   return LAYER_ACTIVE_FORCE;
    1414             : #endif
    1415             : }
    1416             : 
    1417             : class PluginFrameDidCompositeObserver final : public DidCompositeObserver
    1418             : {
    1419             : public:
    1420           0 :   PluginFrameDidCompositeObserver(nsPluginInstanceOwner* aOwner, LayerManager* aLayerManager)
    1421           0 :     : mInstanceOwner(aOwner),
    1422           0 :       mLayerManager(aLayerManager)
    1423             :   {
    1424           0 :   }
    1425           0 :   ~PluginFrameDidCompositeObserver() {
    1426           0 :     mLayerManager->RemoveDidCompositeObserver(this);
    1427           0 :   }
    1428           0 :   void DidComposite() override {
    1429           0 :     mInstanceOwner->DidComposite();
    1430           0 :   }
    1431           0 :   bool IsValid(LayerManager* aLayerManager) {
    1432           0 :     return aLayerManager == mLayerManager;
    1433             :   }
    1434             : 
    1435             : private:
    1436             :   nsPluginInstanceOwner* mInstanceOwner;
    1437             :   RefPtr<LayerManager> mLayerManager;
    1438             : };
    1439             : 
    1440             : already_AddRefed<Layer>
    1441           0 : nsPluginFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
    1442             :                           LayerManager* aManager,
    1443             :                           nsDisplayItem* aItem,
    1444             :                           const ContainerLayerParameters& aContainerParameters)
    1445             : {
    1446           0 :   if (!mInstanceOwner)
    1447           0 :     return nullptr;
    1448             : 
    1449           0 :   NPWindow* window = nullptr;
    1450           0 :   mInstanceOwner->GetWindow(window);
    1451           0 :   if (!window)
    1452           0 :     return nullptr;
    1453             : 
    1454           0 :   if (window->width <= 0 || window->height <= 0)
    1455           0 :     return nullptr;
    1456             : 
    1457             : #if defined(XP_MACOSX)
    1458             :   // window is in "display pixels", but size needs to be in device pixels
    1459             :   // window must be in "display pixels"
    1460             :   double scaleFactor = 1.0;
    1461             :   if (NS_FAILED(mInstanceOwner->GetContentsScaleFactor(&scaleFactor))) {
    1462             :     scaleFactor = 1.0;
    1463             :   }
    1464             : 
    1465             :   size_t intScaleFactor = ceil(scaleFactor);
    1466             : #else
    1467           0 :   size_t intScaleFactor = 1;
    1468             : #endif
    1469             : 
    1470           0 :   IntSize size(window->width * intScaleFactor, window->height * intScaleFactor);
    1471             : 
    1472           0 :   nsRect area = GetContentRectRelativeToSelf() + aItem->ToReferenceFrame();
    1473           0 :   gfxRect r = nsLayoutUtils::RectToGfxRect(area, PresContext()->AppUnitsPerDevPixel());
    1474             :   // to provide crisper and faster drawing.
    1475           0 :   r.Round();
    1476             :   RefPtr<Layer> layer =
    1477           0 :     (aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, aItem));
    1478             : 
    1479           0 :   if (aItem->GetType() == nsDisplayItem::TYPE_PLUGIN) {
    1480           0 :     RefPtr<ImageContainer> container;
    1481             :     // Image for Windowed plugins that support window capturing for scroll
    1482             :     // operations or async windowless rendering.
    1483           0 :     container = mInstanceOwner->GetImageContainer();
    1484           0 :     if (!container) {
    1485             :       // This can occur if our instance is gone or if the current plugin
    1486             :       // configuration does not require a backing image layer.
    1487           0 :       return nullptr;
    1488             :     }
    1489             : 
    1490           0 :     if (!layer) {
    1491           0 :       mInstanceOwner->NotifyPaintWaiter(aBuilder);
    1492             :       // Initialize ImageLayer
    1493           0 :       layer = aManager->CreateImageLayer();
    1494           0 :       if (!layer)
    1495           0 :         return nullptr;
    1496             :     }
    1497             : 
    1498           0 :     NS_ASSERTION(layer->GetType() == Layer::TYPE_IMAGE, "Bad layer type");
    1499           0 :     ImageLayer* imglayer = static_cast<ImageLayer*>(layer.get());
    1500             : #ifdef XP_MACOSX
    1501             :     if (!mInstanceOwner->UseAsyncRendering()) {
    1502             :       mInstanceOwner->DoCocoaEventDrawRect(r, nullptr);
    1503             :     }
    1504             : #endif
    1505             : 
    1506           0 :     imglayer->SetScaleToSize(size, ScaleMode::STRETCH);
    1507           0 :     imglayer->SetContainer(container);
    1508           0 :     SamplingFilter samplingFilter = nsLayoutUtils::GetSamplingFilterForFrame(this);
    1509             : #ifdef MOZ_GFX_OPTIMIZE_MOBILE
    1510             :     if (!aManager->IsCompositingCheap()) {
    1511             :       // Pixman just horrible with bilinear filter scaling
    1512             :       samplingFilter = SamplingFilter::POINT;
    1513             :     }
    1514             : #endif
    1515           0 :     imglayer->SetSamplingFilter(samplingFilter);
    1516             : 
    1517           0 :     layer->SetContentFlags(IsOpaque() ? Layer::CONTENT_OPAQUE : 0);
    1518             : 
    1519           0 :     if (aBuilder->IsPaintingToWindow() &&
    1520           0 :         aBuilder->GetWidgetLayerManager() &&
    1521           0 :         (aBuilder->GetWidgetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT ||
    1522           0 :          aBuilder->GetWidgetLayerManager()->GetBackendType() == LayersBackend::LAYERS_WR) &&
    1523           0 :         mInstanceOwner->UseAsyncRendering())
    1524             :     {
    1525           0 :       RefPtr<LayerManager> lm = aBuilder->GetWidgetLayerManager();
    1526           0 :       if (!mDidCompositeObserver || !mDidCompositeObserver->IsValid(lm)) {
    1527           0 :         mDidCompositeObserver = MakeUnique<PluginFrameDidCompositeObserver>(mInstanceOwner, lm);
    1528             :       }
    1529           0 :       lm->AddDidCompositeObserver(mDidCompositeObserver.get());
    1530             :     }
    1531             : #ifdef MOZ_WIDGET_ANDROID
    1532             :   } else if (aItem->GetType() == nsDisplayItem::TYPE_PLUGIN_VIDEO) {
    1533             :     nsDisplayPluginVideo* videoItem = reinterpret_cast<nsDisplayPluginVideo*>(aItem);
    1534             :     nsNPAPIPluginInstance::VideoInfo* videoInfo = videoItem->VideoInfo();
    1535             : 
    1536             :     RefPtr<ImageContainer> container = mInstanceOwner->GetImageContainerForVideo(videoInfo);
    1537             :     if (!container)
    1538             :       return nullptr;
    1539             : 
    1540             :     if (!layer) {
    1541             :       // Initialize ImageLayer
    1542             :       layer = aManager->CreateImageLayer();
    1543             :       if (!layer)
    1544             :         return nullptr;
    1545             :     }
    1546             : 
    1547             :     ImageLayer* imglayer = static_cast<ImageLayer*>(layer.get());
    1548             :     imglayer->SetContainer(container);
    1549             : 
    1550             :     layer->SetContentFlags(IsOpaque() ? Layer::CONTENT_OPAQUE : 0);
    1551             : 
    1552             :     // Set the offset and size according to the video dimensions
    1553             :     r.MoveBy(videoInfo->mDimensions.TopLeft());
    1554             :     size.width = videoInfo->mDimensions.width;
    1555             :     size.height = videoInfo->mDimensions.height;
    1556             : #endif
    1557             :   } else {
    1558           0 :     NS_ASSERTION(aItem->GetType() == nsDisplayItem::TYPE_PLUGIN_READBACK,
    1559             :                  "Unknown item type");
    1560           0 :     MOZ_ASSERT(!IsOpaque(), "Opaque plugins don't use backgrounds");
    1561             : 
    1562           0 :     if (!layer) {
    1563           0 :       layer = aManager->CreateReadbackLayer();
    1564           0 :       if (!layer)
    1565           0 :         return nullptr;
    1566             :     }
    1567           0 :     NS_ASSERTION(layer->GetType() == Layer::TYPE_READBACK, "Bad layer type");
    1568             : 
    1569           0 :     ReadbackLayer* readback = static_cast<ReadbackLayer*>(layer.get());
    1570           0 :     if (readback->GetSize() != size) {
    1571             :       // This will destroy any old background sink and notify us that the
    1572             :       // background is now unknown
    1573           0 :       readback->SetSink(nullptr);
    1574           0 :       readback->SetSize(size);
    1575             : 
    1576           0 :       if (mBackgroundSink) {
    1577             :         // Maybe we still have a background sink associated with another
    1578             :         // readback layer that wasn't recycled for some reason? Unhook it
    1579             :         // now so that if this frame goes away, it doesn't have a dangling
    1580             :         // reference to us.
    1581           0 :         mBackgroundSink->Destroy();
    1582             :       }
    1583           0 :       mBackgroundSink =
    1584             :         new PluginBackgroundSink(this,
    1585           0 :                                  readback->AllocateSequenceNumber());
    1586           0 :       readback->SetSink(mBackgroundSink);
    1587             :       // The layer has taken ownership of our sink. When either the sink dies
    1588             :       // or the frame dies, the connection from the surviving object is nulled out.
    1589             :     }
    1590             :   }
    1591             : 
    1592             :   // Set a transform on the layer to draw the plugin in the right place
    1593           0 :   gfxPoint p = r.TopLeft() + aContainerParameters.mOffset;
    1594           0 :   Matrix transform = Matrix::Translation(p.x, p.y);
    1595             : 
    1596           0 :   layer->SetBaseTransform(Matrix4x4::From2D(transform));
    1597           0 :   return layer.forget();
    1598             : }
    1599             : 
    1600             : void
    1601           0 : nsPluginFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
    1602             :                            gfxContext& aRenderingContext,
    1603             :                            const nsRect& aDirtyRect, const nsRect& aPluginRect)
    1604             : {
    1605             : #if defined(MOZ_WIDGET_ANDROID)
    1606             :   if (mInstanceOwner) {
    1607             :     gfxRect frameGfxRect =
    1608             :       PresContext()->AppUnitsToGfxUnits(aPluginRect);
    1609             :     gfxRect dirtyGfxRect =
    1610             :       PresContext()->AppUnitsToGfxUnits(aDirtyRect);
    1611             : 
    1612             :     mInstanceOwner->Paint(&aRenderingContext, frameGfxRect, dirtyGfxRect);
    1613             :     return;
    1614             :   }
    1615             : #else
    1616             : # if defined(DEBUG)
    1617             :   // On Desktop, we should have built a layer as we no longer support in-process
    1618             :   // plugins or synchronous painting. We can only get here for windowed plugins
    1619             :   // (which draw themselves), or via some error/unload state.
    1620           0 :   if (mInstanceOwner) {
    1621           0 :     NPWindow *window = nullptr;
    1622           0 :     mInstanceOwner->GetWindow(window);
    1623           0 :     MOZ_ASSERT(!window || window->type == NPWindowTypeWindow);
    1624             :   }
    1625             : # endif
    1626             : #endif
    1627           0 : }
    1628             : 
    1629             : nsresult
    1630           0 : nsPluginFrame::HandleEvent(nsPresContext* aPresContext,
    1631             :                            WidgetGUIEvent* anEvent,
    1632             :                            nsEventStatus* anEventStatus)
    1633             : {
    1634           0 :   NS_ENSURE_ARG_POINTER(anEvent);
    1635           0 :   NS_ENSURE_ARG_POINTER(anEventStatus);
    1636           0 :   nsresult rv = NS_OK;
    1637             : 
    1638           0 :   if (!mInstanceOwner)
    1639           0 :     return NS_ERROR_NULL_POINTER;
    1640             : 
    1641           0 :   mInstanceOwner->ConsiderNewEventloopNestingLevel();
    1642             : 
    1643           0 :   if (anEvent->mMessage == ePluginActivate) {
    1644           0 :     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
    1645           0 :     nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(GetContent());
    1646           0 :     if (fm && elem)
    1647           0 :       return fm->SetFocus(elem, 0);
    1648             :   }
    1649           0 :   else if (anEvent->mMessage == ePluginFocus) {
    1650           0 :     nsIFocusManager* fm = nsFocusManager::GetFocusManager();
    1651           0 :     if (fm) {
    1652           0 :       nsCOMPtr<nsIContent> content = GetContent();
    1653           0 :       return fm->FocusPlugin(content);
    1654             :     }
    1655             :   }
    1656             : 
    1657           0 :   if (mInstanceOwner->SendNativeEvents() &&
    1658           0 :       anEvent->IsNativeEventDelivererForPlugin()) {
    1659           0 :     *anEventStatus = mInstanceOwner->ProcessEvent(*anEvent);
    1660             :     // Due to plugin code reentering Gecko, this frame may be dead at this
    1661             :     // point.
    1662           0 :     return rv;
    1663             :   }
    1664             : 
    1665             : #ifdef XP_WIN
    1666             :   rv = nsFrame::HandleEvent(aPresContext, anEvent, anEventStatus);
    1667             :   return rv;
    1668             : #endif
    1669             : 
    1670             : #ifdef XP_MACOSX
    1671             :   // we want to process some native mouse events in the cocoa event model
    1672             :   if ((anEvent->mMessage == eMouseEnterIntoWidget ||
    1673             :        anEvent->mMessage == eWheel) &&
    1674             :       mInstanceOwner->GetEventModel() == NPEventModelCocoa) {
    1675             :     *anEventStatus = mInstanceOwner->ProcessEvent(*anEvent);
    1676             :     // Due to plugin code reentering Gecko, this frame may be dead at this
    1677             :     // point.
    1678             :     return rv;
    1679             :   }
    1680             : 
    1681             :   // These two calls to nsIPresShell::SetCapturingContext() (on mouse-down
    1682             :   // and mouse-up) are needed to make the routing of mouse events while
    1683             :   // dragging conform to standard OS X practice, and to the Cocoa NPAPI spec.
    1684             :   // See bug 525078 and bug 909678.
    1685             :   if (anEvent->mMessage == eMouseDown) {
    1686             :     nsIPresShell::SetCapturingContent(GetContent(), CAPTURE_IGNOREALLOWED);
    1687             :   }
    1688             : #endif
    1689             : 
    1690           0 :   rv = nsFrame::HandleEvent(aPresContext, anEvent, anEventStatus);
    1691             : 
    1692             :   // We need to be careful from this point because the call to
    1693             :   // nsFrame::HandleEvent() might have killed us.
    1694             : 
    1695             : #ifdef XP_MACOSX
    1696             :   if (anEvent->mMessage == eMouseUp) {
    1697             :     nsIPresShell::SetCapturingContent(nullptr, 0);
    1698             :   }
    1699             : #endif
    1700             : 
    1701           0 :   return rv;
    1702             : }
    1703             : 
    1704             : void
    1705           0 : nsPluginFrame::HandleWheelEventAsDefaultAction(WidgetWheelEvent* aWheelEvent)
    1706             : {
    1707           0 :   MOZ_ASSERT(WantsToHandleWheelEventAsDefaultAction());
    1708           0 :   MOZ_ASSERT(!aWheelEvent->DefaultPrevented());
    1709             : 
    1710           0 :   if (NS_WARN_IF(!mInstanceOwner) ||
    1711           0 :       NS_WARN_IF(aWheelEvent->mMessage != eWheel)) {
    1712           0 :     return;
    1713             :   }
    1714             : 
    1715             :   // If the wheel event has native message, it should may be handled by
    1716             :   // HandleEvent() in the future.  In such case, we should do nothing here.
    1717           0 :   if (NS_WARN_IF(!!aWheelEvent->mPluginEvent)) {
    1718           0 :     return;
    1719             :   }
    1720             : 
    1721           0 :   mInstanceOwner->ProcessEvent(*aWheelEvent);
    1722             :   // We need to assume that the event is always consumed/handled by the
    1723             :   // plugin.  There is no way to know if it's actually consumed/handled.
    1724           0 :   aWheelEvent->mViewPortIsOverscrolled = false;
    1725           0 :   aWheelEvent->mOverflowDeltaX = 0;
    1726           0 :   aWheelEvent->mOverflowDeltaY = 0;
    1727             :   // Consume the event explicitly.
    1728           0 :   aWheelEvent->PreventDefault();
    1729             : }
    1730             : 
    1731             : bool
    1732           0 : nsPluginFrame::WantsToHandleWheelEventAsDefaultAction() const
    1733             : {
    1734             : #ifdef XP_WIN
    1735             :   if (!mInstanceOwner) {
    1736             :     return false;
    1737             :   }
    1738             :   NPWindow* window = nullptr;
    1739             :   mInstanceOwner->GetWindow(window);
    1740             :   // On Windows, only when the plugin is windowless, we need to send wheel
    1741             :   // events as default action.
    1742             :   return window->type == NPWindowTypeDrawable;
    1743             : #else
    1744           0 :   return false;
    1745             : #endif
    1746             : }
    1747             : 
    1748             : nsresult
    1749           0 : nsPluginFrame::GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance)
    1750             : {
    1751           0 :   *aPluginInstance = nullptr;
    1752             : 
    1753           0 :   if (!mInstanceOwner) {
    1754           0 :     return NS_OK;
    1755             :   }
    1756             : 
    1757           0 :   return mInstanceOwner->GetInstance(aPluginInstance);
    1758             : }
    1759             : 
    1760             : nsresult
    1761           0 : nsPluginFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor)
    1762             : {
    1763           0 :   if (!mInstanceOwner) {
    1764           0 :     return NS_ERROR_FAILURE;
    1765             :   }
    1766             : 
    1767           0 :   RefPtr<nsNPAPIPluginInstance> inst;
    1768           0 :   mInstanceOwner->GetInstance(getter_AddRefs(inst));
    1769           0 :   if (!inst) {
    1770           0 :     return NS_ERROR_FAILURE;
    1771             :   }
    1772             : 
    1773           0 :   bool useDOMCursor = static_cast<nsNPAPIPluginInstance*>(inst.get())->UsesDOMForCursor();
    1774           0 :   if (!useDOMCursor) {
    1775           0 :     return NS_ERROR_FAILURE;
    1776             :   }
    1777             : 
    1778           0 :   return nsFrame::GetCursor(aPoint, aCursor);
    1779             : }
    1780             : 
    1781             : void
    1782           0 : nsPluginFrame::SetIsDocumentActive(bool aIsActive)
    1783             : {
    1784           0 :   if (mInstanceOwner) {
    1785           0 :     mInstanceOwner->UpdateDocumentActiveState(aIsActive);
    1786             :   }
    1787           0 : }
    1788             : 
    1789             : // static
    1790             : nsIObjectFrame *
    1791           0 : nsPluginFrame::GetNextObjectFrame(nsPresContext* aPresContext, nsIFrame* aRoot)
    1792             : {
    1793           0 :   for (nsIFrame* child : aRoot->PrincipalChildList()) {
    1794           0 :     nsIObjectFrame* outFrame = do_QueryFrame(child);
    1795           0 :     if (outFrame) {
    1796           0 :       RefPtr<nsNPAPIPluginInstance> pi;
    1797           0 :       outFrame->GetPluginInstance(getter_AddRefs(pi));  // make sure we have a REAL plugin
    1798           0 :       if (pi)
    1799           0 :         return outFrame;
    1800             :     }
    1801             : 
    1802           0 :     outFrame = GetNextObjectFrame(aPresContext, child);
    1803           0 :     if (outFrame)
    1804           0 :       return outFrame;
    1805             :   }
    1806             : 
    1807           0 :   return nullptr;
    1808             : }
    1809             : 
    1810             : /*static*/ void
    1811           0 : nsPluginFrame::BeginSwapDocShells(nsISupports* aSupports, void*)
    1812             : {
    1813           0 :   NS_PRECONDITION(aSupports, "");
    1814           0 :   nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
    1815           0 :   if (!content) {
    1816           0 :     return;
    1817             :   }
    1818             : 
    1819             :   // This function is called from a document content enumerator so we need
    1820             :   // to filter out the nsPluginFrames and ignore the rest.
    1821           0 :   nsIObjectFrame* obj = do_QueryFrame(content->GetPrimaryFrame());
    1822           0 :   if (!obj)
    1823           0 :     return;
    1824             : 
    1825           0 :   nsPluginFrame* objectFrame = static_cast<nsPluginFrame*>(obj);
    1826           0 :   NS_ASSERTION(!objectFrame->mWidget || objectFrame->mWidget->GetParent(),
    1827             :                "Plugin windows must not be toplevel");
    1828           0 :   objectFrame->UnregisterPluginForGeometryUpdates();
    1829             : }
    1830             : 
    1831             : /*static*/ void
    1832           0 : nsPluginFrame::EndSwapDocShells(nsISupports* aSupports, void*)
    1833             : {
    1834           0 :   NS_PRECONDITION(aSupports, "");
    1835           0 :   nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
    1836           0 :   if (!content) {
    1837           0 :     return;
    1838             :   }
    1839             : 
    1840             :   // This function is called from a document content enumerator so we need
    1841             :   // to filter out the nsPluginFrames and ignore the rest.
    1842           0 :   nsIObjectFrame* obj = do_QueryFrame(content->GetPrimaryFrame());
    1843           0 :   if (!obj)
    1844           0 :     return;
    1845             : 
    1846           0 :   nsPluginFrame* objectFrame = static_cast<nsPluginFrame*>(obj);
    1847           0 :   nsRootPresContext* rootPC = objectFrame->PresContext()->GetRootPresContext();
    1848           0 :   NS_ASSERTION(rootPC, "unable to register the plugin frame");
    1849           0 :   nsIWidget* widget = objectFrame->mWidget;
    1850           0 :   if (widget) {
    1851             :     // Reparent the widget.
    1852             :     nsIWidget* parent =
    1853           0 :       rootPC->PresShell()->GetRootFrame()->GetNearestWidget();
    1854           0 :     widget->SetParent(parent);
    1855           0 :     AutoWeakFrame weakFrame(objectFrame);
    1856           0 :     objectFrame->CallSetWindow();
    1857           0 :     if (!weakFrame.IsAlive()) {
    1858           0 :       return;
    1859             :     }
    1860             :   }
    1861             : 
    1862           0 :   if (objectFrame->mInstanceOwner) {
    1863           0 :     objectFrame->RegisterPluginForGeometryUpdates();
    1864             :   }
    1865             : }
    1866             : 
    1867             : nsIFrame*
    1868           0 : NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
    1869             : {
    1870           0 :   return new (aPresShell) nsPluginFrame(aContext);
    1871             : }
    1872             : 
    1873             : bool
    1874           0 : nsPluginFrame::IsPaintedByGecko() const
    1875             : {
    1876             : #ifdef XP_MACOSX
    1877             :   return true;
    1878             : #else
    1879           0 :   return !mWidget;
    1880             : #endif
    1881             : }
    1882             : 
    1883           0 : NS_IMPL_FRAMEARENA_HELPERS(nsPluginFrame)

Generated by: LCOV version 1.13