mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 727421 - Implement full screen support for Flash on Android r=blassey
This commit is contained in:
parent
9550a9264b
commit
1822c63ae0
@ -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 \
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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 = "";
|
||||
@ -1516,18 +1518,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() {
|
||||
|
@ -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);
|
||||
|
@ -136,7 +136,7 @@ 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");
|
||||
jRemovePluginView = jEnv->GetStaticMethodID(jGeckoAppShellClass, "removePluginView", "(Landroid/view/View;Z)V");
|
||||
jNotifyPaintedRect = jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyPaintedRect", "(FFFF)V");
|
||||
|
||||
jHandleGeckoMessage = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "handleGeckoMessage", "(Ljava/lang/String;)Ljava/lang/String;");
|
||||
@ -185,7 +185,7 @@ 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");
|
||||
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");
|
||||
@ -2310,7 +2310,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 +2320,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 +2330,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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user