diff --git a/mobile/android/base/GeckoThread.java b/mobile/android/base/GeckoThread.java index c6c1e4b4c5d..4a6ba2d9a79 100644 --- a/mobile/android/base/GeckoThread.java +++ b/mobile/android/base/GeckoThread.java @@ -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 diff --git a/mozglue/android/APKOpen.cpp b/mozglue/android/APKOpen.cpp index 3ab995f89c4..ffaab5fe12e 100644 --- a/mozglue/android/APKOpen.cpp +++ b/mozglue/android/APKOpen.cpp @@ -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); } diff --git a/toolkit/xre/nsAndroidStartup.cpp b/toolkit/xre/nsAndroidStartup.cpp index 57ceb3d5787..a88c58e5d99 100644 --- a/toolkit/xre/nsAndroidStartup.cpp +++ b/toolkit/xre/nsAndroidStartup.cpp @@ -11,6 +11,7 @@ #include #include +#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 targs; - char *arg = strtok(static_cast(data), " "); + char *arg = strtok(data, " "); while (arg) { targs.AppendElement(arg); arg = strtok(nullptr, " "); diff --git a/widget/android/AndroidBridge.cpp b/widget/android/AndroidBridge.cpp index dd0c52c91e1..26f31fb9883 100644 --- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -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. diff --git a/widget/android/GeneratedJNIWrappers.cpp b/widget/android/GeneratedJNIWrappers.cpp index d0e85614b04..775de94b9ba 100644 --- a/widget/android/GeneratedJNIWrappers.cpp +++ b/widget/android/GeneratedJNIWrappers.cpp @@ -876,6 +876,14 @@ auto GeckoThread::State::INITIAL() -> State::LocalRef return mozilla::jni::Field::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::Get(nullptr, nullptr); +} + constexpr char GeckoThread::State::LAUNCHED_t::name[]; constexpr char GeckoThread::State::LAUNCHED_t::signature[]; diff --git a/widget/android/GeneratedJNIWrappers.h b/widget/android/GeneratedJNIWrappers.h index ea25499365b..1e6ec00451c 100644 --- a/widget/android/GeneratedJNIWrappers.h +++ b/widget/android/GeneratedJNIWrappers.h @@ -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; diff --git a/widget/android/nsAppShell.cpp b/widget/android/nsAppShell.cpp index 9c2f51f7794..5ac14203aaf 100644 --- a/widget/android/nsAppShell.cpp +++ b/widget/android/nsAppShell.cpp @@ -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