Bug 1192082 - Iniialize/deinitialize JNI in nsAppShell; r=snorp

First we need to set the Gecko thread JNIEnv* in nsAndroidStartup, but
after that we can initialize and deinitialize the rest of JNI, including
AndroidBridge, in GeckoAppShell. This makes nsAppShell control the
AndroidBridge lifetime. Over time, parts of the AndroidBridge
functionality will be migrated to nsAppShell.
This commit is contained in:
Jim Chen 2015-08-13 00:53:40 -04:00
parent c6ef3b5faa
commit 03727ba844
7 changed files with 47 additions and 7 deletions

View File

@ -47,6 +47,8 @@ public class GeckoThread extends Thread implements GeckoEventListener {
MOZGLUE_READY,
// After loading the libxul library.
LIBS_READY,
// After initializing nsAppShell and JNI calls.
JNI_READY,
// After initializing frontend JS (corresponding to "Gecko:Ready" event)
RUNNING,
// After leaving Gecko event loop

View File

@ -370,7 +370,7 @@ Java_org_mozilla_gecko_mozglue_GeckoLoader_loadNSSLibsNative(JNIEnv *jenv, jclas
jenv->ReleaseStringUTFChars(jApkName, str);
}
typedef void (*GeckoStart_t)(void *, const nsXREAppData *);
typedef void (*GeckoStart_t)(JNIEnv*, char*, const nsXREAppData*);
extern "C" NS_EXPORT void JNICALL
Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv *jenv, jclass jc, jstring jargs)
@ -387,7 +387,7 @@ Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv *jenv, jclass jc, js
jenv->GetStringUTFRegion(jargs, 0, len, args);
args[len] = '\0';
ElfLoader::Singleton.ExpectShutdown(false);
GeckoStart(args, &sAppData);
GeckoStart(jenv, args, &sAppData);
ElfLoader::Singleton.ExpectShutdown(true);
free(args);
}

View File

@ -11,6 +11,7 @@
#include <string.h>
#include <pthread.h>
#include "mozilla/jni/Utils.h"
#include "nsTArray.h"
#include "nsString.h"
#include "nsIFile.h"
@ -21,8 +22,10 @@
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, MOZ_APP_NAME, args)
extern "C" NS_EXPORT void
GeckoStart(void *data, const nsXREAppData *appData)
GeckoStart(JNIEnv* env, char* data, const nsXREAppData* appData)
{
mozilla::jni::SetGeckoThreadEnv(env);
#ifdef MOZ_CRASHREPORTER
const struct mapping_info *info = getLibraryMapping();
while (info->name) {
@ -38,7 +41,7 @@ GeckoStart(void *data, const nsXREAppData *appData)
}
nsTArray<char *> targs;
char *arg = strtok(static_cast<char *>(data), " ");
char *arg = strtok(data, " ");
while (arg) {
targs.AppendElement(arg);
arg = strtok(nullptr, " ");

View File

@ -47,8 +47,6 @@
#include "SurfaceTexture.h"
#include "GLContextProvider.h"
#include "ANRReporter.h"
using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::jni;
@ -260,7 +258,6 @@ AndroidBridge::AndroidBridge()
jAvailable = inputStream.getMethod("available", "()I");
InitAndroidJavaWrappers(jEnv);
ANRReporter::Init();
}
// Raw JNIEnv variants.

View File

@ -876,6 +876,14 @@ auto GeckoThread::State::INITIAL() -> State::LocalRef
return mozilla::jni::Field<INITIAL_t>::Get(nullptr, nullptr);
}
constexpr char GeckoThread::State::JNI_READY_t::name[];
constexpr char GeckoThread::State::JNI_READY_t::signature[];
auto GeckoThread::State::JNI_READY() -> State::LocalRef
{
return mozilla::jni::Field<JNI_READY_t>::Get(nullptr, nullptr);
}
constexpr char GeckoThread::State::LAUNCHED_t::name[];
constexpr char GeckoThread::State::LAUNCHED_t::signature[];

View File

@ -2069,6 +2069,23 @@ public:
static auto INITIAL() -> State::LocalRef;
public:
struct JNI_READY_t {
typedef State Owner;
typedef State::LocalRef ReturnType;
typedef State::Param SetterType;
typedef mozilla::jni::Args<> Args;
static constexpr char name[] = "JNI_READY";
static constexpr char signature[] =
"Lorg/mozilla/gecko/GeckoThread$State;";
static const bool isStatic = true;
static const bool isMultithreaded = true;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
static auto JNI_READY() -> State::LocalRef;
public:
struct LAUNCHED_t {
typedef State Owner;

View File

@ -56,6 +56,8 @@
#include "mozilla/Logging.h"
#endif
#include "ANRReporter.h"
#ifdef DEBUG_ANDROID_EVENTS
#define EVLOG(args...) ALOG(args)
#else
@ -146,6 +148,15 @@ nsAppShell::nsAppShell()
NS_WARNING("Failed to retrieve PowerManagerService, wakelocks will be broken!");
}
// Initialize JNI and Set the corresponding state in GeckoThread.
if (!jni::IsAvailable()) {
return;
}
AndroidBridge::ConstructBridge();
mozilla::ANRReporter::Init();
widget::GeckoThread::SetState(widget::GeckoThread::State::JNI_READY());
}
nsAppShell::~nsAppShell()
@ -158,6 +169,8 @@ nsAppShell::~nsAppShell()
sPowerManagerService = nullptr;
sWakeLockListener = nullptr;
}
AndroidBridge::DeconstructBridge();
}
void