Issue #1053 - Remove android support from NPAPI

This commit is contained in:
Matt A. Tobin 2020-02-20 12:44:29 -05:00 committed by Roy Tam
commit 49ea8c2f2d
28 changed files with 14 additions and 3639 deletions

View file

@ -87,20 +87,6 @@ static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
#include <gtk/gtk.h>
#endif
#ifdef MOZ_WIDGET_ANDROID
#include "ANPBase.h"
#include "AndroidBridge.h"
#include "ClientLayerManager.h"
#include "nsWindow.h"
static nsPluginInstanceOwner* sFullScreenInstance = nullptr;
using namespace mozilla::dom;
#include <android/log.h>
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#endif
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::layers;
@ -165,29 +151,6 @@ nsPluginInstanceOwner::NotifyPaintWaiter(nsDisplayListBuilder* aBuilder)
}
}
#if MOZ_WIDGET_ANDROID
static void
AttachToContainerAsSurfaceTexture(ImageContainer* container,
nsNPAPIPluginInstance* instance,
const LayoutDeviceRect& rect,
RefPtr<Image>* out_image)
{
MOZ_ASSERT(out_image);
MOZ_ASSERT(!*out_image);
mozilla::gl::AndroidSurfaceTexture* surfTex = instance->AsSurfaceTexture();
if (!surfTex) {
return;
}
RefPtr<Image> img = new SurfaceTextureImage(
surfTex,
gfx::IntSize::Truncate(rect.width, rect.height),
instance->OriginPos());
*out_image = img;
}
#endif
bool
nsPluginInstanceOwner::NeedsScrollImageLayer()
{
@ -211,27 +174,6 @@ nsPluginInstanceOwner::GetImageContainer()
RefPtr<ImageContainer> container;
#if MOZ_WIDGET_ANDROID
LayoutDeviceRect r = GetPluginRect();
// NotifySize() causes Flash to do a bunch of stuff like ask for surfaces to render
// into, set y-flip flags, etc, so we do this at the beginning.
float resolution = mPluginFrame->PresContext()->PresShell()->GetCumulativeResolution();
ScreenSize screenSize = (r * LayoutDeviceToScreenScale(resolution)).Size();
mInstance->NotifySize(nsIntSize::Truncate(screenSize.width, screenSize.height));
container = LayerManager::CreateImageContainer();
if (r.width && r.height) {
// Try to get it as an EGLImage first.
RefPtr<Image> img;
AttachToContainerAsSurfaceTexture(container, mInstance, r, &img);
if (img) {
container->SetCurrentImageInTransaction(img);
}
}
#else
if (NeedsScrollImageLayer()) {
// windowed plugin under e10s
#if defined(XP_WIN)
@ -241,7 +183,6 @@ nsPluginInstanceOwner::GetImageContainer()
// async windowless rendering
mInstance->GetImageContainer(getter_AddRefs(container));
}
#endif
return container.forget();
}
@ -358,11 +299,6 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
mWaitingForPaint = false;
#ifdef MOZ_WIDGET_ANDROID
mFullScreen = false;
mJavaView = nullptr;
#endif
#ifdef XP_WIN
mGotCompositionData = false;
mSentStartComposition = false;
@ -387,10 +323,6 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
PLUG_DeletePluginNativeWindow(mPluginWindow);
mPluginWindow = nullptr;
#ifdef MOZ_WIDGET_ANDROID
RemovePluginView();
#endif
if (mInstance) {
mInstance->SetOwner(nullptr);
}
@ -413,10 +345,6 @@ nsPluginInstanceOwner::SetInstance(nsNPAPIPluginInstance *aInstance)
// from our destructor. This fixes bug 613376.
if (mInstance && !aInstance) {
mInstance->SetOwner(nullptr);
#ifdef MOZ_WIDGET_ANDROID
RemovePluginView();
#endif
}
mInstance = aInstance;
@ -601,7 +529,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
if (!mPluginFrame || !invalidRect || !mWidgetVisible)
return NS_ERROR_FAILURE;
#if defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID)
#ifdef XP_MACOSX
// Each time an asynchronously-drawing plugin sends a new surface to display,
// the image in the ImageContainer is updated and InvalidateRect is called.
// There are different side effects for (sync) Android plugins.
@ -624,6 +552,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect)
}
}
#endif
nsIntRect rect(invalidRect->left,
invalidRect->top,
invalidRect->right - invalidRect->left,
@ -1485,185 +1414,6 @@ nsPluginInstanceOwner::GetEventloopNestingLevel()
return currentLevel;
}
#ifdef MOZ_WIDGET_ANDROID
// Modified version of nsFrame::GetOffsetToCrossDoc that stops when it
// hits an element with a displayport (or runs out of frames). This is
// not really the right thing to do, but it's better than what was here before.
static nsPoint
GetOffsetRootContent(nsIFrame* aFrame)
{
// offset will hold the final offset
// docOffset holds the currently accumulated offset at the current APD, it
// will be converted and added to offset when the current APD changes.
nsPoint offset(0, 0), docOffset(0, 0);
const nsIFrame* f = aFrame;
int32_t currAPD = aFrame->PresContext()->AppUnitsPerDevPixel();
int32_t apd = currAPD;
while (f) {
if (f->GetContent() && nsLayoutUtils::HasDisplayPort(f->GetContent()))
break;
docOffset += f->GetPosition();
nsIFrame* parent = f->GetParent();
if (parent) {
f = parent;
} else {
nsPoint newOffset(0, 0);
f = nsLayoutUtils::GetCrossDocParentFrame(f, &newOffset);
int32_t newAPD = f ? f->PresContext()->AppUnitsPerDevPixel() : 0;
if (!f || newAPD != currAPD) {
// Convert docOffset to the right APD and add it to offset.
offset += docOffset.ScaleToOtherAppUnits(currAPD, apd);
docOffset.x = docOffset.y = 0;
}
currAPD = newAPD;
docOffset += newOffset;
}
}
offset += docOffset.ScaleToOtherAppUnits(currAPD, apd);
return offset;
}
LayoutDeviceRect nsPluginInstanceOwner::GetPluginRect()
{
// Get the offset of the content relative to the page
nsRect bounds = mPluginFrame->GetContentRectRelativeToSelf() + GetOffsetRootContent(mPluginFrame);
LayoutDeviceIntRect rect = LayoutDeviceIntRect::FromAppUnitsToNearest(bounds, mPluginFrame->PresContext()->AppUnitsPerDevPixel());
return LayoutDeviceRect(rect);
}
bool nsPluginInstanceOwner::AddPluginView(const LayoutDeviceRect& aRect /* = LayoutDeviceRect(0, 0, 0, 0) */)
{
if (!mJavaView) {
mJavaView = mInstance->GetJavaSurface();
if (!mJavaView)
return false;
mJavaView = (void*)jni::GetGeckoThreadEnv()->NewGlobalRef((jobject)mJavaView);
}
if (mFullScreen) {
java::GeckoAppShell::AddFullScreenPluginView(jni::Object::Ref::From(jobject(mJavaView)));
sFullScreenInstance = this;
}
return true;
}
void nsPluginInstanceOwner::RemovePluginView()
{
if (!mInstance || !mJavaView)
return;
if (mFullScreen) {
java::GeckoAppShell::RemoveFullScreenPluginView(jni::Object::Ref::From(jobject(mJavaView)));
}
jni::GetGeckoThreadEnv()->DeleteGlobalRef((jobject)mJavaView);
mJavaView = nullptr;
if (mFullScreen)
sFullScreenInstance = nullptr;
}
void
nsPluginInstanceOwner::GetVideos(nsTArray<nsNPAPIPluginInstance::VideoInfo*>& aVideos)
{
if (!mInstance)
return;
mInstance->GetVideos(aVideos);
}
already_AddRefed<ImageContainer>
nsPluginInstanceOwner::GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInfo* aVideoInfo)
{
RefPtr<ImageContainer> container = LayerManager::CreateImageContainer();
if (aVideoInfo->mDimensions.width && aVideoInfo->mDimensions.height) {
RefPtr<Image> img = new SurfaceTextureImage(
aVideoInfo->mSurfaceTexture,
gfx::IntSize::Truncate(aVideoInfo->mDimensions.width, aVideoInfo->mDimensions.height),
gl::OriginPos::BottomLeft);
container->SetCurrentImageInTransaction(img);
}
return container.forget();
}
void nsPluginInstanceOwner::Invalidate() {
NPRect rect;
rect.left = rect.top = 0;
rect.right = mPluginWindow->width;
rect.bottom = mPluginWindow->height;
InvalidateRect(&rect);
}
void nsPluginInstanceOwner::Recomposite() {
nsIWidget* const widget = mPluginFrame->GetNearestWidget();
NS_ENSURE_TRUE_VOID(widget);
LayerManager* const lm = widget->GetLayerManager();
NS_ENSURE_TRUE_VOID(lm);
ClientLayerManager* const clm = lm->AsClientLayerManager();
NS_ENSURE_TRUE_VOID(clm && clm->GetRoot());
clm->SendInvalidRegion(
clm->GetRoot()->GetLocalVisibleRegion().ToUnknownRegion().GetBounds());
clm->Composite();
}
void nsPluginInstanceOwner::RequestFullScreen() {
if (mFullScreen)
return;
// Remove whatever view we currently have (if any, fullscreen or otherwise)
RemovePluginView();
mFullScreen = true;
AddPluginView();
mInstance->NotifyFullScreen(mFullScreen);
}
void nsPluginInstanceOwner::ExitFullScreen() {
if (!mFullScreen)
return;
RemovePluginView();
mFullScreen = false;
int32_t model = mInstance->GetANPDrawingModel();
if (model == kSurface_ANPDrawingModel) {
// We need to do this immediately, otherwise Flash
// sometimes causes a deadlock (bug 762407)
AddPluginView(GetPluginRect());
}
mInstance->NotifyFullScreen(mFullScreen);
// This will cause Paint() to be called, which is where
// we normally add/update views and layers
Invalidate();
}
void nsPluginInstanceOwner::ExitFullScreen(jobject view) {
JNIEnv* env = jni::GetGeckoThreadEnv();
if (sFullScreenInstance && sFullScreenInstance->mInstance &&
env->IsSameObject(view, (jobject)sFullScreenInstance->mInstance->GetJavaSurface())) {
sFullScreenInstance->ExitFullScreen();
}
}
#endif
void
nsPluginInstanceOwner::NotifyHostAsyncInitFailed()
{
@ -1705,27 +1455,6 @@ nsPluginInstanceOwner::NotifyDestroyPending()
nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
{
#ifdef MOZ_WIDGET_ANDROID
if (mInstance) {
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = kLifecycle_ANPEventType;
nsAutoString eventType;
aFocusEvent->GetType(eventType);
if (eventType.EqualsLiteral("focus")) {
event.data.lifecycle.action = kGainFocus_ANPLifecycleAction;
}
else if (eventType.EqualsLiteral("blur")) {
event.data.lifecycle.action = kLoseFocus_ANPLifecycleAction;
}
else {
NS_ASSERTION(false, "nsPluginInstanceOwner::DispatchFocusToPlugin, wierd eventType");
}
mInstance->HandleEvent(&event, nullptr);
}
#endif
#ifndef XP_MACOSX
if (!mPluginWindow || (mPluginWindow->type == NPWindowTypeWindow)) {
// continue only for cases without child window
@ -2786,96 +2515,6 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
rv = nsEventStatus_eConsumeNoDefault;
#endif
#ifdef MOZ_WIDGET_ANDROID
// this code supports windowless plugins
{
// The plugin needs focus to receive keyboard and touch events
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm) {
nsCOMPtr<nsIDOMElement> elem = do_QueryReferent(mContent);
fm->SetFocus(elem, 0);
}
}
switch(anEvent.mClass) {
case eMouseEventClass:
{
switch (anEvent.mMessage) {
case eMouseClick:
case eMouseDoubleClick:
case eMouseAuxClick:
// Button up/down events sent instead.
return rv;
default:
break;
}
// Get reference point relative to plugin origin.
const nsPresContext* presContext = mPluginFrame->PresContext();
nsPoint appPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(&anEvent, mPluginFrame) -
mPluginFrame->GetContentRectRelativeToSelf().TopLeft();
nsIntPoint pluginPoint(presContext->AppUnitsToDevPixels(appPoint.x),
presContext->AppUnitsToDevPixels(appPoint.y));
switch (anEvent.mMessage) {
case eMouseMove:
{
// are these going to be touch events?
// pluginPoint.x;
// pluginPoint.y;
}
break;
case eMouseDown:
{
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = kMouse_ANPEventType;
event.data.mouse.action = kDown_ANPMouseAction;
event.data.mouse.x = pluginPoint.x;
event.data.mouse.y = pluginPoint.y;
mInstance->HandleEvent(&event, nullptr, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
}
break;
case eMouseUp:
{
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = kMouse_ANPEventType;
event.data.mouse.action = kUp_ANPMouseAction;
event.data.mouse.x = pluginPoint.x;
event.data.mouse.y = pluginPoint.y;
mInstance->HandleEvent(&event, nullptr, NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
}
break;
default:
break;
}
}
break;
case eKeyboardEventClass:
{
const WidgetKeyboardEvent& keyEvent = *anEvent.AsKeyboardEvent();
LOG("Firing eKeyboardEventClass %d %d\n",
keyEvent.mKeyCode, keyEvent.mCharCode);
// pluginEvent is initialized by nsWindow::InitKeyEvent().
const ANPEvent* pluginEvent = static_cast<const ANPEvent*>(keyEvent.mPluginEvent);
if (pluginEvent) {
MOZ_ASSERT(pluginEvent->inSize == sizeof(ANPEvent));
MOZ_ASSERT(pluginEvent->eventType == kKey_ANPEventType);
mInstance->HandleEvent(const_cast<ANPEvent*>(pluginEvent),
nullptr,
NS_PLUGIN_CALL_SAFE_TO_REENTER_GECKO);
}
}
break;
default:
break;
}
rv = nsEventStatus_eConsumeNoDefault;
#endif
return rv;
}
@ -2922,10 +2561,6 @@ nsPluginInstanceOwner::Destroy()
this, true);
content->RemoveSystemEventListener(NS_LITERAL_STRING("text"), this, true);
#if MOZ_WIDGET_ANDROID
RemovePluginView();
#endif
if (mWidget) {
if (mPluginWindow) {
mPluginWindow->SetPluginWidget(nullptr);
@ -2995,72 +2630,6 @@ void nsPluginInstanceOwner::Paint(const RECT& aDirty, HDC aDC)
}
#endif
#ifdef MOZ_WIDGET_ANDROID
void nsPluginInstanceOwner::Paint(gfxContext* aContext,
const gfxRect& aFrameRect,
const gfxRect& aDirtyRect)
{
if (!mInstance || !mPluginFrame || !mPluginDocumentActiveState || mFullScreen)
return;
int32_t model = mInstance->GetANPDrawingModel();
if (model == kSurface_ANPDrawingModel) {
if (!AddPluginView(GetPluginRect())) {
Invalidate();
}
return;
}
if (model != kBitmap_ANPDrawingModel)
return;
#ifdef ANP_BITMAP_DRAWING_MODEL
static RefPtr<gfxImageSurface> pluginSurface;
if (pluginSurface == nullptr ||
aFrameRect.width != pluginSurface->Width() ||
aFrameRect.height != pluginSurface->Height()) {
pluginSurface = new gfxImageSurface(gfx::IntSize(aFrameRect.width, aFrameRect.height),
SurfaceFormat::A8R8G8B8_UINT32);
if (!pluginSurface)
return;
}
// Clears buffer. I think this is needed.
gfxUtils::ClearThebesSurface(pluginSurface);
ANPEvent event;
event.inSize = sizeof(ANPEvent);
event.eventType = 4;
event.data.draw.model = 1;
event.data.draw.clip.top = 0;
event.data.draw.clip.left = 0;
event.data.draw.clip.bottom = aFrameRect.width;
event.data.draw.clip.right = aFrameRect.height;
event.data.draw.data.bitmap.format = kRGBA_8888_ANPBitmapFormat;
event.data.draw.data.bitmap.width = aFrameRect.width;
event.data.draw.data.bitmap.height = aFrameRect.height;
event.data.draw.data.bitmap.baseAddr = pluginSurface->Data();
event.data.draw.data.bitmap.rowBytes = aFrameRect.width * 4;
if (!mInstance)
return;
mInstance->HandleEvent(&event, nullptr);
aContext->SetOp(gfx::CompositionOp::OP_SOURCE);
aContext->SetSource(pluginSurface, gfxPoint(aFrameRect.x, aFrameRect.y));
aContext->Clip(aFrameRect);
aContext->Paint();
#endif
}
#endif
#if defined(MOZ_X11)
void nsPluginInstanceOwner::Paint(gfxContext* aContext,
const gfxRect& aFrameRect,
@ -3663,24 +3232,6 @@ nsPluginInstanceOwner::UpdateDocumentActiveState(bool aIsActive)
#ifndef XP_MACOSX
UpdateWindowPositionAndClipRect(true);
#ifdef MOZ_WIDGET_ANDROID
if (mInstance) {
if (!mPluginDocumentActiveState) {
RemovePluginView();
}
mInstance->NotifyOnScreen(mPluginDocumentActiveState);
// This is, perhaps, incorrect. It is supposed to be sent
// when "the webview has paused or resumed". The side effect
// is that Flash video players pause or resume (if they were
// playing before) based on the value here. I personally think
// we want that on Android when switching to another tab, so
// that's why we call it here.
mInstance->NotifyForeground(mPluginDocumentActiveState);
}
#endif // #ifdef MOZ_WIDGET_ANDROID
// We don't have a connection to PluginWidgetParent in the chrome
// process when dealing with tab visibility changes, so this needs
// to be forwarded over after the active state is updated. If we