Bug 669200 - Implement base PPluginWidget classes for managing plugin windows via content. r=billm

This commit is contained in:
Jim Mathies 2014-11-12 14:59:19 -06:00
parent 2216111e8c
commit 198d1229be
9 changed files with 384 additions and 1 deletions

View File

@ -17,6 +17,7 @@
#include "mozilla/IntentionalCrash.h"
#include "mozilla/docshell/OfflineCacheUpdateChild.h"
#include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestChild.h"
#include "mozilla/plugins/PluginWidgetChild.h"
#include "mozilla/ipc/DocumentRendererChild.h"
#include "mozilla/ipc/FileDescriptorUtils.h"
#include "mozilla/layers/ActiveElementManager.h"
@ -3109,6 +3110,42 @@ TabChild::RecvUIResolutionChanged()
return true;
}
mozilla::plugins::PPluginWidgetChild*
TabChild::AllocPPluginWidgetChild()
{
return new mozilla::plugins::PluginWidgetChild();
}
bool
TabChild::DeallocPPluginWidgetChild(mozilla::plugins::PPluginWidgetChild* aActor)
{
delete aActor;
return true;
}
already_AddRefed<nsIWidget>
TabChild::CreatePluginWidget(nsIWidget* aParent)
{
mozilla::plugins::PluginWidgetChild* child =
static_cast<mozilla::plugins::PluginWidgetChild*>(SendPPluginWidgetConstructor());
if (!child) {
NS_ERROR("couldn't create PluginWidgetChild");
return nullptr;
}
nsCOMPtr<nsIWidget> pluginWidget = nsIWidget::CreatePluginProxyWidget(this, child);
if (!pluginWidget) {
NS_ERROR("couldn't create PluginWidgetProxy");
return nullptr;
}
nsresult rv = pluginWidget->Create(aParent, 0, nsIntRect(nsIntPoint(0, 0),
nsIntSize(0, 0)), nullptr, nullptr);
if (NS_FAILED(rv)) {
NS_WARNING("Creating native plugin widget on the chrome side failed.");
}
return pluginWidget.forget();
}
TabChildGlobal::TabChildGlobal(TabChildBase* aTabChild)
: mTabChild(aTabChild)
{

View File

@ -52,6 +52,10 @@ namespace widget {
struct AutoCacheNativeKeyCommands;
}
namespace plugins {
class PluginWidgetChild;
}
namespace dom {
class TabChild;
@ -484,6 +488,13 @@ public:
virtual bool RecvUIResolutionChanged() MOZ_OVERRIDE;
/**
* Native widget remoting protocol for use with windowed plugins with e10s.
*/
PPluginWidgetChild* AllocPPluginWidgetChild() MOZ_OVERRIDE;
bool DeallocPPluginWidgetChild(PPluginWidgetChild* aActor) MOZ_OVERRIDE;
already_AddRefed<nsIWidget> CreatePluginWidget(nsIWidget* aParent);
protected:
virtual ~TabChild();

View File

@ -15,6 +15,7 @@
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/PContentPermissionRequestParent.h"
#include "mozilla/dom/indexedDB/ActorsParent.h"
#include "mozilla/plugins/PluginWidgetParent.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/Hal.h"
#include "mozilla/ipc/DocumentRendererParent.h"
@ -2247,6 +2248,19 @@ TabParent::RecvRemotePaintIsReady()
return true;
}
mozilla::plugins::PPluginWidgetParent*
TabParent::AllocPPluginWidgetParent()
{
return new mozilla::plugins::PluginWidgetParent();
}
bool
TabParent::DeallocPPluginWidgetParent(mozilla::plugins::PPluginWidgetParent* aActor)
{
delete aActor;
return true;
}
class FakeChannel MOZ_FINAL : public nsIChannel,
public nsIAuthPromptCallback,
public nsIInterfaceRequestor,

View File

@ -347,6 +347,14 @@ public:
return mTabId;
}
nsIntPoint GetChildProcessOffset();
/**
* Native widget remoting protocol for use with windowed plugins with e10s.
*/
virtual PPluginWidgetParent* AllocPPluginWidgetParent() MOZ_OVERRIDE;
virtual bool DeallocPPluginWidgetParent(PPluginWidgetParent* aActor) MOZ_OVERRIDE;
protected:
bool ReceiveMessage(const nsString& aMessage,
bool aSync,
@ -367,7 +375,6 @@ protected:
nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
bool AllowContentIME();
nsIntPoint GetChildProcessOffset();
virtual PRenderFrameParent* AllocPRenderFrameParent(ScrollingBehavior* aScrolling,
TextureFactoryIdentifier* aTextureFactoryIdentifier,

View File

@ -0,0 +1,35 @@
/* 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 "mozilla/plugins/PluginWidgetChild.h"
#include "PluginWidgetProxy.h"
namespace mozilla {
namespace plugins {
PluginWidgetChild::PluginWidgetChild() :
mWidget(nullptr)
{
MOZ_COUNT_CTOR(PluginWidgetChild);
}
PluginWidgetChild::~PluginWidgetChild()
{
MOZ_COUNT_DTOR(PluginWidgetChild);
}
void
PluginWidgetChild::ActorDestroy(ActorDestroyReason aWhy)
{
if (mWidget) {
mWidget->ChannelDestroyed();
}
mWidget = nullptr;
}
} // namespace plugins
} // namespace mozilla

View File

@ -0,0 +1,31 @@
/* 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/. */
#ifndef mozilla_plugins_PluginWidgetParent_h
#define mozilla_plugins_PluginWidgetParent_h
#include "mozilla/plugins/PPluginWidgetChild.h"
namespace mozilla {
namespace widget {
class PluginWidgetProxy;
}
namespace plugins {
class PluginWidgetChild : public PPluginWidgetChild
{
public:
PluginWidgetChild();
virtual ~PluginWidgetChild();
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
mozilla::widget::PluginWidgetProxy* mWidget;
};
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_PluginWidgetParent_h

View File

@ -0,0 +1,195 @@
/* 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 "PluginWidgetParent.h"
#include "mozilla/dom/TabParent.h"
#include "nsComponentManagerUtils.h"
#include "nsWidgetsCID.h"
#include "nsDebug.h"
using namespace mozilla::widget;
#define PWLOG(...)
// #define PWLOG(...) printf_stderr(__VA_ARGS__)
namespace mozilla {
namespace plugins {
static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID);
// This macro returns true to prevent an abort in the child process when
// ipc message delivery fails.
#define ENSURE_CHANNEL { \
if (!mWidget) { \
NS_WARNING("called on an invalid remote widget."); \
return true; \
} \
}
PluginWidgetParent::PluginWidgetParent()
{
PWLOG("PluginWidgetParent::PluginWidgetParent()\n");
MOZ_COUNT_CTOR(PluginWidgetParent);
}
PluginWidgetParent::~PluginWidgetParent()
{
PWLOG("PluginWidgetParent::~PluginWidgetParent()\n");
MOZ_COUNT_DTOR(PluginWidgetParent);
// A destroy call can actually get skipped if a widget is associated
// with the last out-of-process page, make sure and cleanup any left
// over widgets if we have them.
if (mWidget) {
mWidget->Destroy();
mWidget = nullptr;
}
}
mozilla::dom::TabParent*
PluginWidgetParent::GetTabParent()
{
return static_cast<mozilla::dom::TabParent*>(Manager());
}
void
PluginWidgetParent::ActorDestroy(ActorDestroyReason aWhy)
{
PWLOG("PluginWidgetParent::ActorDestroy()\n");
}
// When plugins run in chrome, nsPluginNativeWindow(Plat) implements platform
// specific functionality that wraps plugin widgets. With e10s we currently
// bypass this code since we can't connect up platform specific bits in the
// content process. We may need to instantiate nsPluginNativeWindow here and
// enable some of its logic.
bool
PluginWidgetParent::RecvCreate()
{
PWLOG("PluginWidgetParent::RecvCreate()\n");
nsresult rv;
mWidget = do_CreateInstance(kWidgetCID, &rv);
// This returns the top level window widget
nsCOMPtr<nsIWidget> parentWidget = GetTabParent()->GetWidget();
nsWidgetInitData initData;
initData.mWindowType = eWindowType_plugin_ipc_chrome;
initData.mUnicode = false;
initData.clipChildren = true;
initData.clipSiblings = true;
rv = mWidget->Create(parentWidget.get(), nullptr, nsIntRect(0,0,0,0),
nullptr, &initData);
if (NS_FAILED(rv)) {
mWidget->Destroy();
mWidget = nullptr;
return false;
}
mWidget->EnableDragDrop(true);
mWidget->Show(false);
mWidget->Enable(false);
// Force the initial position down into content. If we miss an
// initial position update this insures the widget doesn't overlap
// chrome.
RecvMove(0, 0);
return true;
}
bool
PluginWidgetParent::RecvDestroy()
{
ENSURE_CHANNEL;
PWLOG("PluginWidgetParent::RecvDestroy()\n");
mWidget->Destroy();
mWidget = nullptr;
return true;
}
bool
PluginWidgetParent::RecvShow(const bool& aState)
{
ENSURE_CHANNEL;
PWLOG("PluginWidgetParent::RecvShow(%d)\n", aState);
mWidget->Show(aState);
return true;
}
bool
PluginWidgetParent::RecvSetFocus(const bool& aRaise)
{
ENSURE_CHANNEL;
PWLOG("PluginWidgetParent::RecvSetFocus(%d)\n", aRaise);
mWidget->SetFocus(aRaise);
return true;
}
bool
PluginWidgetParent::RecvInvalidate(const nsIntRect& aRect)
{
ENSURE_CHANNEL;
PWLOG("PluginWidgetParent::RecvInvalidate(%d, %d, %d, %d)\n", aRect.x, aRect.y, aRect.width, aRect.height);
mWidget->Invalidate(aRect);
return true;
}
bool
PluginWidgetParent::RecvGetNativePluginPort(uintptr_t* value)
{
ENSURE_CHANNEL;
PWLOG("PluginWidgetParent::RecvGetNativeData()\n");
*value = (uintptr_t)mWidget->GetNativeData(NS_NATIVE_PLUGIN_PORT);
return true;
}
bool
PluginWidgetParent::RecvResize(const nsIntRect& aRect)
{
ENSURE_CHANNEL;
PWLOG("PluginWidgetParent::RecvResize(%d, %d, %d, %d)\n", aRect.x, aRect.y, aRect.width, aRect.height);
mWidget->Resize(aRect.width, aRect.height, true);
return true;
}
bool
PluginWidgetParent::RecvMove(const double& aX, const double& aY)
{
ENSURE_CHANNEL;
PWLOG("PluginWidgetParent::RecvMove(%f, %f)\n", aX, aY);
// This returns the top level window
nsCOMPtr<nsIWidget> widget = GetTabParent()->GetWidget();
if (!widget) {
// return true otherwise ipc will abort the content process, crashing
// all tabs.
return true;
}
// Passed in coords are at the tab origin, adjust to the main window.
nsIntPoint offset = GetTabParent()->GetChildProcessOffset();
offset.x = abs(offset.x);
offset.y = abs(offset.y);
offset += nsIntPoint(ceil(aX), ceil(aY));
mWidget->Move(offset.x, offset.y);
return true;
}
bool
PluginWidgetParent::RecvSetWindowClipRegion(const nsTArray<nsIntRect>& Regions,
const bool& aIntersectWithExisting)
{
ENSURE_CHANNEL;
PWLOG("PluginWidgetParent::RecvSetWindowClipRegion()\n");
mWidget->SetWindowClipRegion(Regions, aIntersectWithExisting);
return true;
}
} // namespace plugins
} // namespace mozilla

View File

@ -0,0 +1,49 @@
/* 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/. */
#ifndef mozilla_plugins_PluginWidgetParent_h
#define mozilla_plugins_PluginWidgetParent_h
#include "mozilla/plugins/PPluginWidgetParent.h"
#include "nsIWidget.h"
#include "nsCOMPtr.h"
namespace mozilla {
namespace dom {
class TabParent;
}
namespace plugins {
class PluginWidgetParent : public PPluginWidgetParent
{
public:
PluginWidgetParent();
virtual ~PluginWidgetParent();
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool RecvCreate() MOZ_OVERRIDE;
virtual bool RecvDestroy() MOZ_OVERRIDE;
virtual bool RecvShow(const bool& aState) MOZ_OVERRIDE;
virtual bool RecvSetFocus(const bool& aRaise) MOZ_OVERRIDE;
virtual bool RecvInvalidate(const nsIntRect& aRect) MOZ_OVERRIDE;
virtual bool RecvGetNativePluginPort(uintptr_t* value) MOZ_OVERRIDE;
virtual bool RecvResize(const nsIntRect& aRect) MOZ_OVERRIDE;
virtual bool RecvMove(const double& aX, const double& aY) MOZ_OVERRIDE;
virtual bool RecvSetWindowClipRegion(const nsTArray<nsIntRect>& Regions,
const bool& aIntersectWithExisting) MOZ_OVERRIDE;
private:
// The tab our connection is associated with.
mozilla::dom::TabParent* GetTabParent();
// The chrome side native widget.
nsCOMPtr<nsIWidget> mWidget;
};
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_PluginWidgetParent_h

View File

@ -36,6 +36,8 @@ EXPORTS.mozilla.plugins += [
'PluginStreamChild.h',
'PluginStreamParent.h',
'PluginUtilsOSX.h',
'PluginWidgetChild.h',
'PluginWidgetParent.h',
'ScopedMethodFactory.h',
'StreamNotifyChild.h',
'StreamNotifyParent.h',
@ -92,6 +94,8 @@ UNIFIED_SOURCES += [
SOURCES += [
'PluginInstanceChild.cpp', # 'PluginThreadCallback' : ambiguous symbol
'PluginModuleChild.cpp', # Redefinition of mozilla::WindowsDllInterceptor sUser32Intercept
'PluginWidgetChild.cpp',
'PluginWidgetParent.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':