Bug 727421 - Implement full screen support for Flash on Android r=blassey

This commit is contained in:
James Willcox 2012-05-30 12:10:49 -04:00
parent 85579b42e5
commit b194413562
15 changed files with 300 additions and 92 deletions

View File

@ -102,6 +102,7 @@ endif
LOCAL_INCLUDES += \
-DSK_BUILD_FOR_ANDROID_NDK \
-I$(topsrcdir)/widget/android \
-I$(topsrcdir)/widget/xpwidgets \
-I$(topsrcdir)/xpcom/base/ \
-I$(topsrcdir)/gfx/skia/include/core \
-I$(topsrcdir)/gfx/skia/include/config \

View File

@ -25,7 +25,7 @@ static nsresult GetOwner(NPP instance, nsPluginInstanceOwner** owner) {
return pinst->GetOwner((nsIPluginInstanceOwner**)owner);
}
static ANPNativeWindow anp_native_window_acquireNativeWindow(NPP instance) {
static ANPNativeWindow anp_native_window_acquireNativeWindow(NPP instance) {
nsRefPtr<nsPluginInstanceOwner> owner;
if (NS_FAILED(GetOwner(instance, getter_AddRefs(owner))))
return NULL;

View File

@ -143,6 +143,14 @@ static bool init() {
gSurfaceFunctions.lock = (int (*)(void*, SurfaceInfo*, void*))dlsym(handle, "_ZN7android7Surface4lockEPNS0_11SurfaceInfoEPNS_6RegionEb");
gSurfaceFunctions.unlockAndPost = (int (*)(void*))dlsym(handle, "_ZN7android7Surface13unlockAndPostEv");
if (!gSurfaceFunctions.lock) {
// Stuff changed in 3.0/4.0
handle = dlopen("libgui.so", RTLD_LAZY);
gSurfaceFunctions.lock = (int (*)(void*, SurfaceInfo*, void*))dlsym(handle, "_ZN7android7Surface4lockEPNS0_11SurfaceInfoEPNS_6RegionE");
gSurfaceFunctions.unlockAndPost = (int (*)(void*))dlsym(handle, "_ZN7android7Surface13unlockAndPostEv");
}
handle = dlopen("libui.so", RTLD_LAZY);
if (!handle) {
LOG("Failed to open libui.so");
@ -158,6 +166,7 @@ static bool init() {
return gSurfaceFunctions.initialized;
}
// FIXME: All of this should be changed to use the equivalent things in AndroidBridge, bug 758612
static bool anp_surface_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRectI* dirtyRect) {
if (!bitmap || !surfaceView) {
return false;

View File

@ -3,6 +3,7 @@
* 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 "base/basictypes.h"
#include "assert.h"
#include "ANPBase.h"
#include <android/log.h>
@ -11,12 +12,20 @@
#include "nsIPluginInstanceOwner.h"
#include "nsPluginInstanceOwner.h"
#include "nsWindow.h"
#include "mozilla/dom/ScreenOrientation.h"
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
#define ASSIGN(obj, name) (obj)->name = anp_window_##name
using namespace mozilla;
using namespace mozilla::widget;
using namespace mozilla::dom;
static nsresult GetOwner(NPP instance, nsPluginInstanceOwner** owner) {
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
return pinst->GetOwner((nsIPluginInstanceOwner**)owner);
}
void
anp_window_setVisibleRects(NPP instance, const ANPRectI rects[], int32_t count)
@ -54,13 +63,27 @@ anp_window_showKeyboard(NPP instance, bool value)
void
anp_window_requestFullScreen(NPP instance)
{
NOT_IMPLEMENTED();
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
nsRefPtr<nsPluginInstanceOwner> owner;
if (NS_FAILED(GetOwner(instance, getter_AddRefs(owner)))) {
return;
}
owner->RequestFullScreen();
}
void
anp_window_exitFullScreen(NPP instance)
{
NOT_IMPLEMENTED();
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
nsRefPtr<nsPluginInstanceOwner> owner;
if (NS_FAILED(GetOwner(instance, getter_AddRefs(owner)))) {
return;
}
owner->ExitFullScreen();
}
void
@ -69,12 +92,6 @@ anp_window_requestCenterFitZoom(NPP instance)
NOT_IMPLEMENTED();
}
static nsresult GetOwner(NPP instance, nsPluginInstanceOwner** owner) {
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
return pinst->GetOwner((nsIPluginInstanceOwner**)owner);
}
ANPRectI
anp_window_visibleRect(NPP instance)
{
@ -98,7 +115,29 @@ anp_window_visibleRect(NPP instance)
void anp_window_requestFullScreenOrientation(NPP instance, ANPScreenOrientation orientation)
{
NOT_IMPLEMENTED();
short newOrientation;
// Convert to the ActivityInfo equivalent
switch (orientation) {
case kFixedLandscape_ANPScreenOrientation:
newOrientation = eScreenOrientation_LandscapePrimary;
break;
case kFixedPortrait_ANPScreenOrientation:
newOrientation = eScreenOrientation_PortraitPrimary;
break;
case kLandscape_ANPScreenOrientation:
newOrientation = eScreenOrientation_Landscape;
break;
case kPortrait_ANPScreenOrientation:
newOrientation = eScreenOrientation_Portrait;
break;
default:
newOrientation = eScreenOrientation_None;
break;
}
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
pinst->SetFullScreenOrientation(newOrientation);
}
void InitWindowInterface(ANPWindowInterfaceV0 *i) {

View File

@ -698,6 +698,28 @@ struct ANPWindowInterfaceV1 : ANPWindowInterfaceV0 {
ANPRectI (*visibleRect)(NPP instance);
};
enum ANPScreenOrientations {
/** No preference specified: let the system decide the best orientation.
*/
kDefault_ANPScreenOrientation = 0,
/** Would like to have the screen in a landscape orientation, but it will
not allow for 180 degree rotations.
*/
kFixedLandscape_ANPScreenOrientation = 1,
/** Would like to have the screen in a portrait orientation, but it will
not allow for 180 degree rotations.
*/
kFixedPortrait_ANPScreenOrientation = 2,
/** Would like to have the screen in landscape orientation, but can use the
sensor to change which direction the screen is facing.
*/
kLandscape_ANPScreenOrientation = 3,
/** Would like to have the screen in portrait orientation, but can use the
sensor to change which direction the screen is facing.
*/
kPortrait_ANPScreenOrientation = 4
};
typedef int32_t ANPScreenOrientation;
struct ANPWindowInterfaceV2 : ANPWindowInterfaceV1 {

View File

@ -3,6 +3,11 @@
* 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/. */
#ifdef MOZ_WIDGET_ANDROID
// For ScreenOrientation.h
#include "base/basictypes.h"
#endif
#include "prlog.h"
#include "prmem.h"
#include "nscore.h"
@ -35,6 +40,7 @@
#include "mozilla/Mutex.h"
#include "mozilla/CondVar.h"
#include "AndroidBridge.h"
#include "mozilla/dom/ScreenOrientation.h"
class PluginEventRunnable : public nsRunnable
{
@ -74,6 +80,7 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance()
mSurface(nsnull),
mANPDrawingModel(0),
mOnScreen(true),
mFullScreenOrientation(dom::eScreenOrientation_LandscapePrimary),
#endif
mRunning(NOT_STARTED),
mWindowless(false),
@ -743,63 +750,29 @@ void nsNPAPIPluginInstance::MemoryPressure()
SendLifecycleEvent(this, kFreeMemory_ANPLifecycleAction);
}
void nsNPAPIPluginInstance::NotifyFullScreen(bool aFullScreen)
{
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::NotifyFullScreen this=%p\n",this));
if (RUNNING != mRunning)
return;
SendLifecycleEvent(this, aFullScreen ? kEnterFullScreen_ANPLifecycleAction : kExitFullScreen_ANPLifecycleAction);
}
void nsNPAPIPluginInstance::SetANPDrawingModel(PRUint32 aModel)
{
mANPDrawingModel = aModel;
}
class SurfaceGetter : public nsRunnable {
public:
SurfaceGetter(nsNPAPIPluginInstance* aInstance, NPPluginFuncs* aPluginFunctions, NPP_t aNPP) :
mInstance(aInstance), mPluginFunctions(aPluginFunctions), mNPP(aNPP) {
}
~SurfaceGetter() {
}
nsresult Run() {
void* surface;
(*mPluginFunctions->getvalue)(&mNPP, kJavaSurface_ANPGetValue, &surface);
mInstance->SetJavaSurface(surface);
return NS_OK;
}
void RequestSurface() {
JNIEnv* env = GetJNIForThread();
if (!env)
return;
if (!mozilla::AndroidBridge::Bridge()) {
PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance null AndroidBridge"));
return;
}
mozilla::AndroidBridge::Bridge()->PostToJavaThread(env, this);
}
private:
nsNPAPIPluginInstance* mInstance;
NPP_t mNPP;
NPPluginFuncs* mPluginFunctions;
};
void* nsNPAPIPluginInstance::GetJavaSurface()
{
if (mANPDrawingModel != kSurface_ANPDrawingModel)
void* surface = nsnull;
nsresult rv = GetValueFromPlugin(kJavaSurface_ANPGetValue, &surface);
if (NS_FAILED(rv))
return nsnull;
return mSurface;
}
void nsNPAPIPluginInstance::SetJavaSurface(void* aSurface)
{
mSurface = aSurface;
}
void nsNPAPIPluginInstance::RequestJavaSurface()
{
if (mSurfaceGetter.get())
return;
mSurfaceGetter = new SurfaceGetter(this, mPlugin->PluginFuncs(), mNPP);
((SurfaceGetter*)mSurfaceGetter.get())->RequestSurface();
return surface;
}
void nsNPAPIPluginInstance::PostEvent(void* event)

View File

@ -123,6 +123,7 @@ public:
void NotifyForeground(bool aForeground);
void NotifyOnScreen(bool aOnScreen);
void MemoryPressure();
void NotifyFullScreen(bool aFullScreen);
bool IsOnScreen() {
return mOnScreen;
@ -131,12 +132,14 @@ public:
PRUint32 GetANPDrawingModel() { return mANPDrawingModel; }
void SetANPDrawingModel(PRUint32 aModel);
// This stuff is for kSurface_ANPDrawingModel
void* GetJavaSurface();
void SetJavaSurface(void* aSurface);
void RequestJavaSurface();
void PostEvent(void* event);
// These are really mozilla::dom::ScreenOrientation, but it's
// difficult to include that here
PRUint32 FullScreenOrientation() { return mFullScreenOrientation; }
void SetFullScreenOrientation(PRUint32 orientation) { mFullScreenOrientation = orientation; }
#endif
nsresult NewStreamListener(const char* aURL, void* notifyData,
@ -221,6 +224,8 @@ protected:
nsTArray<nsCOMPtr<PluginEventRunnable>> mPostedEvents;
void PopPostedEvent(PluginEventRunnable* r);
PRUint32 mFullScreenOrientation;
#endif
enum {

View File

@ -87,6 +87,10 @@ static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
#include "ANPBase.h"
#include "AndroidBridge.h"
#include "AndroidMediaLayer.h"
#include "nsWindow.h"
static nsPluginInstanceOwner* sFullScreenInstance = nsnull;
using namespace mozilla::dom;
#include <android/log.h>
@ -305,7 +309,9 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
#ifdef MOZ_WIDGET_ANDROID
mInverted = false;
mFullScreen = false;
mLayer = nsnull;
mJavaView = nsnull;
#endif
}
@ -1725,31 +1731,39 @@ void nsPluginInstanceOwner::SendSize(int width, int height)
mInstance->HandleEvent(&event, nsnull);
}
bool nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect)
bool nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect /* = gfxRect(0, 0, 0, 0) */)
{
void* javaSurface = mInstance->GetJavaSurface();
if (!javaSurface) {
mInstance->RequestJavaSurface();
return false;
if (!mJavaView) {
mJavaView = mInstance->GetJavaSurface();
if (!mJavaView)
return false;
mJavaView = (void*)AndroidBridge::GetJNIEnv()->NewGlobalRef((jobject)mJavaView);
}
if (AndroidBridge::Bridge())
AndroidBridge::Bridge()->AddPluginView((jobject)javaSurface, aRect);
AndroidBridge::Bridge()->AddPluginView((jobject)mJavaView, aRect, mFullScreen, mInstance->FullScreenOrientation());
if (mFullScreen)
sFullScreenInstance = this;
return true;
}
void nsPluginInstanceOwner::RemovePluginView()
{
if (!mInstance)
return;
void* surface = mInstance->GetJavaSurface();
if (!surface)
if (!mInstance || !mJavaView)
return;
if (AndroidBridge::Bridge())
AndroidBridge::Bridge()->RemovePluginView((jobject)surface);
AndroidBridge::Bridge()->RemovePluginView((jobject)mJavaView, mFullScreen);
AndroidBridge::GetJNIEnv()->DeleteGlobalRef((jobject)mJavaView);
mJavaView = nsnull;
if (mFullScreen)
sFullScreenInstance = nsnull;
}
void nsPluginInstanceOwner::Invalidate() {
@ -1760,6 +1774,47 @@ void nsPluginInstanceOwner::Invalidate() {
InvalidateRect(&rect);
}
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;
PRInt32 model = mInstance->GetANPDrawingModel();
if (model == kSurface_ANPDrawingModel) {
// We need to invalidate the plugin rect so Paint() gets called above.
// This will cause the view to be re-added. Gross.
Invalidate();
}
mInstance->NotifyFullScreen(mFullScreen);
}
void nsPluginInstanceOwner::ExitFullScreen(jobject view) {
JNIEnv* env = AndroidBridge::GetJNIEnv();
if (env && sFullScreenInstance && sFullScreenInstance->mInstance &&
env->IsSameObject(view, (jobject)sFullScreenInstance->mInstance->GetJavaSurface())) {
sFullScreenInstance->ExitFullScreen();
}
}
#endif
nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
@ -2871,7 +2926,7 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
const gfxRect& aFrameRect,
const gfxRect& aDirtyRect)
{
if (!mInstance || !mObjectFrame || !mPluginDocumentActiveState)
if (!mInstance || !mObjectFrame || !mPluginDocumentActiveState || mFullScreen)
return;
PRInt32 model = mInstance->GetANPDrawingModel();

View File

@ -277,6 +277,12 @@ public:
}
void Invalidate();
void RequestFullScreen();
void ExitFullScreen();
// Called from AndroidJNI when we removed the fullscreen view.
static void ExitFullScreen(jobject view);
#endif
private:
@ -293,10 +299,13 @@ private:
#ifdef MOZ_WIDGET_ANDROID
void SendSize(int width, int height);
bool AddPluginView(const gfxRect& aRect);
bool AddPluginView(const gfxRect& aRect = gfxRect(0, 0, 0, 0));
void RemovePluginView();
bool mInverted;
bool mFullScreen;
void* mJavaView;
// For kOpenGL_ANPDrawingModel
nsRefPtr<mozilla::AndroidMediaLayer> mLayer;

View File

@ -109,6 +109,8 @@ abstract public class GeckoApp
private AboutHomeContent mAboutHomeContent;
private static AbsoluteLayout mPluginContainer;
private View mFullScreenPluginView;
private int mRestoreMode = GeckoAppShell.RESTORE_NONE;
private boolean mInitialized = false;
@ -1350,12 +1352,38 @@ abstract public class GeckoApp
tabs.closeTab(tab);
}
void addPluginView(final View view, final Rect rect) {
private void addFullScreenPluginView(View view, int orientation) {
if (mFullScreenPluginView != null) {
Log.w(LOGTAG, "Already have a fullscreen plugin view");
return;
}
setFullScreen(true);
mBrowserToolbar.hide();
if (orientation != GeckoScreenOrientationListener.eScreenOrientation_None)
GeckoScreenOrientationListener.getInstance().lockScreenOrientation(orientation);
view.setWillNotDraw(false);
if (view instanceof SurfaceView) {
((SurfaceView) view).setZOrderOnTop(true);
}
mPluginContainer.addView(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
mFullScreenPluginView = view;
}
void addPluginView(final View view, final Rect rect, final boolean isFullScreen, final int orientation) {
mMainHandler.post(new Runnable() {
public void run() {
Tabs tabs = Tabs.getInstance();
Tab tab = tabs.getSelectedTab();
if (isFullScreen) {
addFullScreenPluginView(view, orientation);
return;
}
PluginLayer layer = (PluginLayer) tab.getPluginLayer(view);
if (layer == null) {
layer = new PluginLayer(view, rect, mLayerController.getView().getRenderer().getMaxTextureSize());
@ -1370,12 +1398,39 @@ abstract public class GeckoApp
});
}
void removePluginView(final View view) {
private void removeFullScreenPluginView(View view) {
if (mFullScreenPluginView == null) {
Log.w(LOGTAG, "Don't have a fullscreen plugin view");
return;
}
if (mFullScreenPluginView != view) {
Log.w(LOGTAG, "Passed view is not the current full screen view");
return;
}
GeckoAppShell.onFullScreenPluginHidden(view);
GeckoScreenOrientationListener.getInstance().unlockScreenOrientation();
setFullScreen(false);
mBrowserToolbar.show();
mPluginContainer.removeView(view);
mFullScreenPluginView = null;
}
void removePluginView(final View view, final boolean isFullScreen) {
mMainHandler.post(new Runnable() {
public void run() {
Tabs tabs = Tabs.getInstance();
Tab tab = tabs.getSelectedTab();
if (isFullScreen) {
removeFullScreenPluginView(view);
return;
}
PluginLayer layer = (PluginLayer) tab.removePluginLayer(view);
if (layer != null) {
layer.destroy();
@ -2601,6 +2656,11 @@ abstract public class GeckoApp
return;
}
if (mFullScreenPluginView != null) {
removePluginView(mFullScreenPluginView, true);
return;
}
SiteIdentityPopup identityPopup = SiteIdentityPopup.getInstance();
if (identityPopup.isShowing()) {
identityPopup.dismiss();

View File

@ -207,6 +207,8 @@ public class GeckoAppShell
public static native SurfaceBits getSurfaceBits(Surface surface);
public static native void onFullScreenPluginHidden(View view);
private static class GeckoMediaScannerClient implements MediaScannerConnectionClient {
private String mFile = "";
private String mMimeType = "";
@ -1514,18 +1516,19 @@ public class GeckoAppShell
public static void addPluginView(View view,
int x, int y,
int w, int h)
int w, int h,
boolean isFullScreen, int orientation)
{
ImmutableViewportMetrics pluginViewport;
Log.i(LOGTAG, "addPluginView:" + view + " @ x:" + x + " y:" + y + " w:" + w + " h:" + h);
Log.i(LOGTAG, "addPluginView:" + view + " @ x:" + x + " y:" + y + " w:" + w + " h:" + h + "fullscreen: " + isFullScreen + " orientation: " + orientation);
GeckoApp.mAppContext.addPluginView(view, new Rect(x, y, x + w, y + h));
GeckoApp.mAppContext.addPluginView(view, new Rect(x, y, x + w, y + h), isFullScreen, orientation);
}
public static void removePluginView(View view) {
Log.i(LOGTAG, "removePluginView:" + view);
GeckoApp.mAppContext.removePluginView(view);
public static void removePluginView(View view, boolean isFullScreen) {
Log.i(LOGTAG, "removePluginView:" + view + " fullscreen: " + isFullScreen);
GeckoApp.mAppContext.removePluginView(view, isFullScreen);
}
public static Surface createSurface() {

View File

@ -319,6 +319,7 @@ SHELL_WRAPPER7(notifyGotNextMessage, jint, jstring, jstring, jstring, jlong, jin
SHELL_WRAPPER3(notifyReadingMessageListFailed, jint, jint, jlong)
SHELL_WRAPPER2(notifyFilePickerResult, jstring, jlong)
SHELL_WRAPPER1_WITH_RETURN(getSurfaceBits, jobject, jobject)
SHELL_WRAPPER1(onFullScreenPluginHidden, jobject)
static void * xul_handle = NULL;
static void * sqlite_handle = NULL;
@ -736,6 +737,7 @@ loadGeckoLibs(const char *apkName)
GETFUNC(notifyReadingMessageListFailed);
GETFUNC(notifyFilePickerResult);
GETFUNC(getSurfaceBits);
GETFUNC(onFullScreenPluginHidden);
#undef GETFUNC
sStartupTimeline = (uint64_t *)__wrap_dlsym(xul_handle, "_ZN7mozilla15StartupTimeline16sStartupTimelineE");
gettimeofday(&t1, 0);

View File

@ -136,7 +136,6 @@ AndroidBridge::Init(JNIEnv *jEnv,
jEnableBatteryNotifications = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableBatteryNotifications", "()V");
jDisableBatteryNotifications = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "disableBatteryNotifications", "()V");
jGetCurrentBatteryInformation = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getCurrentBatteryInformation", "()[D");
jRemovePluginView = jEnv->GetStaticMethodID(jGeckoAppShellClass, "removePluginView", "(Landroid/view/View;)V");
jNotifyPaintedRect = jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyPaintedRect", "(FFFF)V");
jHandleGeckoMessage = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "handleGeckoMessage", "(Ljava/lang/String;)Ljava/lang/String;");
@ -185,7 +184,9 @@ AndroidBridge::Init(JNIEnv *jEnv,
#ifdef MOZ_JAVA_COMPOSITOR
jPumpMessageLoop = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "pumpMessageLoop", "()V");
jAddPluginView = jEnv->GetStaticMethodID(jGeckoAppShellClass, "addPluginView", "(Landroid/view/View;IIII)V");
jAddPluginView = jEnv->GetStaticMethodID(jGeckoAppShellClass, "addPluginView", "(Landroid/view/View;IIIIZI)V");
jRemovePluginView = jEnv->GetStaticMethodID(jGeckoAppShellClass, "removePluginView", "(Landroid/view/View;Z)V");
jCreateSurface = jEnv->GetStaticMethodID(jGeckoAppShellClass, "createSurface", "()Landroid/view/Surface;");
jShowSurface = jEnv->GetStaticMethodID(jGeckoAppShellClass, "showSurface", "(Landroid/view/Surface;IIIIZZ)V");
jHideSurface = jEnv->GetStaticMethodID(jGeckoAppShellClass, "hideSurface", "(Landroid/view/Surface;)V");
@ -196,7 +197,8 @@ AndroidBridge::Init(JNIEnv *jEnv,
AndroidGLController::Init(jEnv);
AndroidEGLObject::Init(jEnv);
#else
jAddPluginView = jEnv->GetStaticMethodID(jGeckoAppShellClass, "addPluginView", "(Landroid/view/View;DDDD)V");
jAddPluginView = jEnv->GetStaticMethodID(jGeckoAppShellClass, "addPluginView", "(Landroid/view/View;DDDD)V");
jRemovePluginView = jEnv->GetStaticMethodID(jGeckoAppShellClass, "removePluginView", "(Landroid/view/View;)V");
#endif
InitAndroidJavaWrappers(jEnv);
@ -2310,7 +2312,7 @@ NS_IMETHODIMP nsAndroidBridge::SetBrowserApp(nsIAndroidBrowserApp *aBrowserApp)
}
void
AndroidBridge::AddPluginView(jobject view, const gfxRect& rect) {
AndroidBridge::AddPluginView(jobject view, const gfxRect& rect, bool isFullScreen, int orientation) {
JNIEnv *env = GetJNIEnv();
if (!env)
return;
@ -2320,7 +2322,8 @@ AndroidBridge::AddPluginView(jobject view, const gfxRect& rect) {
#if MOZ_JAVA_COMPOSITOR
env->CallStaticVoidMethod(sBridge->mGeckoAppShellClass,
sBridge->jAddPluginView, view,
(int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
(int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height,
isFullScreen, orientation);
#else
env->CallStaticVoidMethod(sBridge->mGeckoAppShellClass,
sBridge->jAddPluginView, view,
@ -2329,14 +2332,14 @@ AndroidBridge::AddPluginView(jobject view, const gfxRect& rect) {
}
void
AndroidBridge::RemovePluginView(jobject view)
AndroidBridge::RemovePluginView(jobject view, bool isFullScreen)
{
JNIEnv *env = GetJNIEnv();
if (!env)
return;
AutoLocalJNIFrame jniFrame(env, 0);
env->CallStaticVoidMethod(mGeckoAppShellClass, jRemovePluginView, view);
env->CallStaticVoidMethod(mGeckoAppShellClass, jRemovePluginView, view, isFullScreen);
}
extern "C"

View File

@ -340,8 +340,8 @@ public:
void ShowSurface(jobject surface, const gfxRect& aRect, bool aInverted, bool aBlend);
void HideSurface(jobject surface);
void AddPluginView(jobject view, const gfxRect& rect);
void RemovePluginView(jobject view);
void AddPluginView(jobject view, const gfxRect& rect, bool isFullScreen, int orientation);
void RemovePluginView(jobject view, bool isFullScreen);
// These methods don't use a ScreenOrientation because it's an
// enum and that would require including the header which requires

View File

@ -37,6 +37,7 @@
#include "mozilla/dom/sms/SmsParent.h"
#include "nsISmsRequestManager.h"
#include "nsISmsDatabaseService.h"
#include "nsPluginInstanceOwner.h"
using namespace mozilla;
using namespace mozilla::dom::sms;
@ -974,6 +975,32 @@ cleanup:
return surfaceBits;
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_onFullScreenPluginHidden(JNIEnv* jenv, jclass, jobject view)
{
class ExitFullScreenRunnable : public nsRunnable {
public:
ExitFullScreenRunnable(jobject view) : mView(view) {}
NS_IMETHODIMP Run() {
JNIEnv* env = AndroidBridge::GetJNIEnv();
if (!env) {
NS_WARNING("Failed to acquire JNI env, can't exit plugin fullscreen mode");
return NS_OK;
}
nsPluginInstanceOwner::ExitFullScreen(mView);
env->DeleteGlobalRef(mView);
return NS_OK;
}
private:
jobject mView;
};
nsCOMPtr<nsIRunnable> runnable = new ExitFullScreenRunnable(jenv->NewGlobalRef(view));
NS_DispatchToMainThread(runnable);
}
#endif
}