зеркало из https://github.com/mozilla/gecko-dev.git
Bug 730890 - Install and run an Android Looper on Gecko main thread r=cjones
This commit is contained in:
Родитель
7db0b87ef1
Коммит
578bae396e
|
@ -67,20 +67,11 @@ anp_event_postEvent(NPP inst, const ANPEvent* event)
|
|||
{
|
||||
LOG("%s", __PRETTY_FUNCTION__);
|
||||
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
if (!mozilla::AndroidBridge::Bridge()) {
|
||||
LOG("no bridge in %s!!!!", __PRETTY_FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(inst->ndata);
|
||||
NPPluginFuncs* pluginFunctions = pinst->GetPlugin()->PluginFuncs();
|
||||
mozilla::AndroidBridge::Bridge()->PostToJavaThread(env,
|
||||
new PluginEventRunnable(inst, const_cast<ANPEvent*>(event), pluginFunctions),
|
||||
true);
|
||||
PluginEventRunnable* e = new PluginEventRunnable(inst, const_cast<ANPEvent*>(event), pluginFunctions);
|
||||
|
||||
NS_DispatchToMainThread(e);
|
||||
LOG("returning from %s", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,10 @@
|
|||
#include "base/logging.h"
|
||||
#include "base/scoped_nsautorelease_pool.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "AndroidBridge.h"
|
||||
#endif
|
||||
|
||||
using mozilla::ipc::DoWorkRunnable;
|
||||
using mozilla::ipc::MessagePump;
|
||||
using mozilla::ipc::MessagePumpForChildProcess;
|
||||
|
@ -115,6 +119,13 @@ MessagePump::Run(MessagePump::Delegate* aDelegate)
|
|||
if (!keep_running_)
|
||||
break;
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
// This processes messages in the Android Looper. Note that we only
|
||||
// get here if the normal Gecko event loop has been awoken above.
|
||||
// Bug 750713
|
||||
AndroidBridge::Bridge()->PumpMessageLoop();
|
||||
#endif
|
||||
|
||||
did_work |= aDelegate->DoDelayedWork(&delayed_work_time_);
|
||||
|
||||
if (did_work && delayed_work_time_.is_null())
|
||||
|
|
|
@ -155,6 +155,8 @@ public class GeckoAppShell
|
|||
|
||||
private static boolean mLocationHighAccuracy = false;
|
||||
|
||||
private static Handler sGeckoHandler;
|
||||
|
||||
/* The Android-side API: API methods that Android calls */
|
||||
|
||||
// Initialization methods
|
||||
|
@ -264,6 +266,10 @@ public class GeckoAppShell
|
|||
return GeckoApp.mAppContext.mMainHandler;
|
||||
}
|
||||
|
||||
public static Handler getGeckoHandler() {
|
||||
return sGeckoHandler;
|
||||
}
|
||||
|
||||
public static Handler getHandler() {
|
||||
return GeckoBackgroundThread.getHandler();
|
||||
}
|
||||
|
@ -458,6 +464,9 @@ public class GeckoAppShell
|
|||
}
|
||||
|
||||
public static void runGecko(String apkPath, String args, String url, String type, boolean restoreSession) {
|
||||
Looper.prepare();
|
||||
sGeckoHandler = new Handler();
|
||||
|
||||
// run gecko -- it will spawn its own thread
|
||||
GeckoAppShell.nativeInit();
|
||||
|
||||
|
@ -2120,6 +2129,28 @@ public class GeckoAppShell
|
|||
GeckoScreenOrientationListener.getInstance().unlockScreenOrientation();
|
||||
}
|
||||
|
||||
public static void pumpMessageLoop() {
|
||||
// We're going to run the Looper below, but we need a way to break out, so
|
||||
// we post this Runnable that throws a RuntimeException. This causes the loop
|
||||
// to exit without marking the Looper as dead. The Runnable is added to the
|
||||
// end of the queue, so it will be executed after anything
|
||||
// else that has been added prior.
|
||||
//
|
||||
// A more civilized method would obviously be preferred. Looper.quit(),
|
||||
// however, marks the Looper as dead and it cannot be prepared or run
|
||||
// again. And since you can only have a single Looper per thread,
|
||||
// here we are.
|
||||
sGeckoHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
Looper.loop();
|
||||
} catch(Exception ex) {}
|
||||
}
|
||||
|
||||
static class AsyncResultHandler extends GeckoApp.FilePickerResultHandler {
|
||||
private long mId;
|
||||
AsyncResultHandler(long id) {
|
||||
|
|
|
@ -215,6 +215,8 @@ AndroidBridge::Init(JNIEnv *jEnv,
|
|||
jSurfacePointerField = jEnv->GetFieldID(jSurfaceClass, "mNativeSurface", "I");
|
||||
|
||||
#ifdef MOZ_JAVA_COMPOSITOR
|
||||
jPumpMessageLoop = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "pumpMessageLoop", "()V");
|
||||
|
||||
jAddPluginView = jEnv->GetStaticMethodID(jGeckoAppShellClass, "addPluginView", "(Landroid/view/View;IIII)V");
|
||||
jCreateSurface = jEnv->GetStaticMethodID(jGeckoAppShellClass, "createSurface", "()Landroid/view/Surface;");
|
||||
jShowSurface = jEnv->GetStaticMethodID(jGeckoAppShellClass, "showSurface", "(Landroid/view/Surface;IIIIZZ)V");
|
||||
|
@ -2186,6 +2188,23 @@ AndroidBridge::UnlockScreenOrientation()
|
|||
mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jUnlockScreenOrientation);
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::PumpMessageLoop()
|
||||
{
|
||||
#if MOZ_JAVA_COMPOSITOR
|
||||
JNIEnv* env = GetJNIEnv();
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
AutoLocalJNIFrame frame(env);
|
||||
|
||||
if ((void*)pthread_self() != mThread)
|
||||
return;
|
||||
|
||||
env->CallStaticVoidMethod(mGeckoAppShellClass, jPumpMessageLoop);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* attribute nsIAndroidBrowserApp browserApp; */
|
||||
NS_IMETHODIMP nsAndroidBridge::GetBrowserApp(nsIAndroidBrowserApp * *aBrowserApp)
|
||||
{
|
||||
|
|
|
@ -451,6 +451,8 @@ public:
|
|||
void LockScreenOrientation(const dom::ScreenOrientationWrapper& aOrientation);
|
||||
void UnlockScreenOrientation();
|
||||
|
||||
void PumpMessageLoop();
|
||||
|
||||
protected:
|
||||
static AndroidBridge *sBridge;
|
||||
|
||||
|
@ -569,6 +571,7 @@ protected:
|
|||
jmethodID jDisableScreenOrientationNotifications;
|
||||
jmethodID jLockScreenOrientation;
|
||||
jmethodID jUnlockScreenOrientation;
|
||||
jmethodID jPumpMessageLoop;
|
||||
|
||||
// For native surface stuff
|
||||
jclass jSurfaceClass;
|
||||
|
|
Загрузка…
Ссылка в новой задаче