widget/PluginWidgetProxy.cpp
author Doug Turner <doug.turner@gmail.com>
Tue, 03 Feb 2015 17:00:00 +0100
changeset 243715 840987c23fc597bdaad4567c2387ba1aa06c65d0
parent 239679 99bad02916c630f5ddaed2f11308952b0f5d69ba
child 252249 93976782a910a6545e5f0f38baf45fba871543e2
permissions -rw-r--r--
Bug 1045229 - Beacons are not associated with windows. The current window based filtering that the network monitor does will skip requests that come from sendBeacon(). Here we explictly look to see if the network channel is from beacon by looking at the loadinfo. r=dcamp, a=sledru

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "PluginWidgetProxy.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/plugins/PluginWidgetChild.h"
#include "nsDebug.h"

#define PWLOG(...)
// #define PWLOG(...) printf_stderr(__VA_ARGS__)

/* static */
already_AddRefed<nsIWidget>
nsIWidget::CreatePluginProxyWidget(TabChild* aTabChild,
                                   mozilla::plugins::PluginWidgetChild* aActor)
{
  nsCOMPtr<nsIWidget> widget =
    new mozilla::widget::PluginWidgetProxy(aTabChild, aActor);
  return widget.forget();
}

namespace mozilla {
namespace widget {

NS_IMPL_ISUPPORTS_INHERITED(PluginWidgetProxy, PuppetWidget, nsIWidget)

#define ENSURE_CHANNEL do {                                   \
  if (!mActor) {                                              \
    NS_WARNING("called on an invalid channel.");              \
    return NS_ERROR_FAILURE;                                  \
  }                                                           \
} while (0)

PluginWidgetProxy::PluginWidgetProxy(dom::TabChild* aTabChild,
                                     mozilla::plugins::PluginWidgetChild* aActor) :
  PuppetWidget(aTabChild),
  mActor(aActor)
{
  // See ChannelDestroyed() in the header
  mActor->mWidget = this;
}

PluginWidgetProxy::~PluginWidgetProxy()
{
  PWLOG("PluginWidgetProxy::~PluginWidgetProxy()\n");
}

NS_IMETHODIMP
PluginWidgetProxy::Create(nsIWidget*        aParent,
                          nsNativeWidget    aNativeParent,
                          const nsIntRect&  aRect,
                          nsDeviceContext*  aContext,
                          nsWidgetInitData* aInitData)
{
  ENSURE_CHANNEL;
  PWLOG("PluginWidgetProxy::Create()\n");

  if (!mActor->SendCreate()) {
    NS_WARNING("failed to create chrome widget, plugins won't paint.");
  }

  BaseCreate(aParent, aRect, aContext, aInitData);

  mBounds = aRect;
  mEnabled = true;
  mVisible = true;

  mActor->SendResize(mBounds);

  return NS_OK;
}

NS_IMETHODIMP
PluginWidgetProxy::SetParent(nsIWidget* aNewParent)
{
  mParent = aNewParent;

  nsCOMPtr<nsIWidget> kungFuDeathGrip(this);
  nsIWidget* parent = GetParent();
  if (parent) {
    parent->RemoveChild(this);
  }
  if (aNewParent) {
    aNewParent->AddChild(this);
  }
  return NS_OK;
}

nsIWidget*
PluginWidgetProxy::GetParent(void)
{
  return mParent.get();
}

NS_IMETHODIMP
PluginWidgetProxy::Destroy()
{
  PWLOG("PluginWidgetProxy::Destroy()\n");

  if (mActor) {
    mActor->SendShow(false);
    mActor->SendDestroy();
    mActor->mWidget = nullptr;
    mActor->Send__delete__(mActor);
    mActor = nullptr;
  }

  return PuppetWidget::Destroy();
}

NS_IMETHODIMP
PluginWidgetProxy::Show(bool aState)
{
  ENSURE_CHANNEL;
  mActor->SendShow(aState);
  mVisible = aState;
  return NS_OK;
}

NS_IMETHODIMP
PluginWidgetProxy::Invalidate(const nsIntRect& aRect)
{
  ENSURE_CHANNEL;
  mActor->SendInvalidate(aRect);
  return NS_OK;
}

void*
PluginWidgetProxy::GetNativeData(uint32_t aDataType)
{
  if (!mActor) {
    return nullptr;
  }
  switch (aDataType) {
    case NS_NATIVE_PLUGIN_PORT:
    case NS_NATIVE_WINDOW:
    case NS_NATIVE_SHAREABLE_WINDOW:
      break;
    default:
      NS_WARNING("PluginWidgetProxy::GetNativeData received request for unsupported data type.");
      return nullptr;
  }
  uintptr_t value = 0;
  mActor->SendGetNativePluginPort(&value);
  PWLOG("PluginWidgetProxy::GetNativeData %p\n", (void*)value);
  return (void*)value;
}

NS_IMETHODIMP
PluginWidgetProxy::Resize(double aWidth, double aHeight, bool aRepaint)
{
  ENSURE_CHANNEL;
  PWLOG("PluginWidgetProxy::Resize(%0.2f, %0.2f, %d)\n", aWidth, aHeight, aRepaint);
  nsIntRect oldBounds = mBounds;
  mBounds.SizeTo(nsIntSize(NSToIntRound(aWidth), NSToIntRound(aHeight)));
  mActor->SendResize(mBounds);
  if (!oldBounds.IsEqualEdges(mBounds) && mAttachedWidgetListener) {
    mAttachedWidgetListener->WindowResized(this, mBounds.width, mBounds.height);
  }
  return NS_OK;
}

NS_IMETHODIMP
PluginWidgetProxy::Resize(double aX, double aY, double aWidth,
                          double aHeight, bool aRepaint)
{
  nsresult rv = Move(aX, aY);
  if (NS_FAILED(rv)) {
    return rv;
  }
  return Resize(aWidth, aHeight, aRepaint);
}

NS_IMETHODIMP
PluginWidgetProxy::Move(double aX, double aY)
{
  ENSURE_CHANNEL;
  PWLOG("PluginWidgetProxy::Move(%0.2f, %0.2f)\n", aX, aY);
  mActor->SendMove(aX, aY);
  if (mAttachedWidgetListener) {
    mAttachedWidgetListener->WindowMoved(this, aX, aY);
  }
  return NS_OK;
}

NS_IMETHODIMP
PluginWidgetProxy::SetFocus(bool aRaise)
{
  ENSURE_CHANNEL;
  PWLOG("PluginWidgetProxy::SetFocus(%d)\n", aRaise);
  mActor->SendSetFocus(aRaise);
  return NS_OK;
}

nsresult
PluginWidgetProxy::SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
                                       bool aIntersectWithExisting)
{
  ENSURE_CHANNEL;
  mActor->SendSetWindowClipRegion(aRects, aIntersectWithExisting);
  nsBaseWidget::SetWindowClipRegion(aRects, aIntersectWithExisting);
  return NS_OK;
}

}  // namespace widget
}  // namespace mozilla