зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1305271 - 1. Move GetClassGlobalRef out of AndroidBridge; r=snorp
Move GetClassGlobalRef in AndroidBridge to GetClassRef in jni/Utils. The new function now returns a local reference instead of a global reference.
This commit is contained in:
Родитель
40fd25db11
Коммит
39ed66e9ec
|
@ -65,33 +65,6 @@ AndroidBridge* AndroidBridge::sBridge = nullptr;
|
||||||
static jobject sGlobalContext = nullptr;
|
static jobject sGlobalContext = nullptr;
|
||||||
nsDataHashtable<nsStringHashKey, nsString> AndroidBridge::sStoragePaths;
|
nsDataHashtable<nsStringHashKey, nsString> AndroidBridge::sStoragePaths;
|
||||||
|
|
||||||
jclass AndroidBridge::GetClassGlobalRef(JNIEnv* env, const char* className)
|
|
||||||
{
|
|
||||||
// First try the default class loader.
|
|
||||||
auto classRef = Class::LocalRef::Adopt(
|
|
||||||
env, env->FindClass(className));
|
|
||||||
|
|
||||||
if (!classRef && sBridge && sBridge->mClassLoader) {
|
|
||||||
// If the default class loader failed but we have an app class loader, try that.
|
|
||||||
// Clear the pending exception from failed FindClass call above.
|
|
||||||
env->ExceptionClear();
|
|
||||||
classRef = Class::LocalRef::Adopt(env, jclass(
|
|
||||||
env->CallObjectMethod(sBridge->mClassLoader.Get(),
|
|
||||||
sBridge->mClassLoaderLoadClass,
|
|
||||||
StringParam(className, env).Get())));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!classRef) {
|
|
||||||
ALOG(">>> FATAL JNI ERROR! FindClass(className=\"%s\") failed. "
|
|
||||||
"Did ProGuard optimize away something it shouldn't have?",
|
|
||||||
className);
|
|
||||||
env->ExceptionDescribe();
|
|
||||||
MOZ_CRASH();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Class::GlobalRef(env, classRef).Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
jmethodID AndroidBridge::GetMethodID(JNIEnv* env, jclass jClass,
|
jmethodID AndroidBridge::GetMethodID(JNIEnv* env, jclass jClass,
|
||||||
const char* methodName, const char* methodType)
|
const char* methodName, const char* methodType)
|
||||||
{
|
{
|
||||||
|
@ -189,11 +162,6 @@ AndroidBridge::AndroidBridge()
|
||||||
JNIEnv* const jEnv = jni::GetGeckoThreadEnv();
|
JNIEnv* const jEnv = jni::GetGeckoThreadEnv();
|
||||||
AutoLocalJNIFrame jniFrame(jEnv);
|
AutoLocalJNIFrame jniFrame(jEnv);
|
||||||
|
|
||||||
mClassLoader = Object::GlobalRef(jEnv, java::GeckoThread::ClsLoader());
|
|
||||||
mClassLoaderLoadClass = GetMethodID(
|
|
||||||
jEnv, jEnv->GetObjectClass(mClassLoader.Get()),
|
|
||||||
"loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
|
|
||||||
|
|
||||||
mMessageQueue = java::GeckoThread::MsgQueue();
|
mMessageQueue = java::GeckoThread::MsgQueue();
|
||||||
auto msgQueueClass = Class::LocalRef::Adopt(
|
auto msgQueueClass = Class::LocalRef::Adopt(
|
||||||
jEnv, jEnv->GetObjectClass(mMessageQueue.Get()));
|
jEnv, jEnv->GetObjectClass(mMessageQueue.Get()));
|
||||||
|
|
|
@ -263,7 +263,6 @@ public:
|
||||||
static jstring NewJavaString(AutoLocalJNIFrame* frame, const char* string);
|
static jstring NewJavaString(AutoLocalJNIFrame* frame, const char* string);
|
||||||
static jstring NewJavaString(AutoLocalJNIFrame* frame, const nsACString& string);
|
static jstring NewJavaString(AutoLocalJNIFrame* frame, const nsACString& string);
|
||||||
|
|
||||||
static jclass GetClassGlobalRef(JNIEnv* env, const char* className);
|
|
||||||
static jfieldID GetFieldID(JNIEnv* env, jclass jClass, const char* fieldName, const char* fieldType);
|
static jfieldID GetFieldID(JNIEnv* env, jclass jClass, const char* fieldName, const char* fieldType);
|
||||||
static jfieldID GetStaticFieldID(JNIEnv* env, jclass jClass, const char* fieldName, const char* fieldType);
|
static jfieldID GetStaticFieldID(JNIEnv* env, jclass jClass, const char* fieldName, const char* fieldType);
|
||||||
static jmethodID GetMethodID(JNIEnv* env, jclass jClass, const char* methodName, const char* methodType);
|
static jmethodID GetMethodID(JNIEnv* env, jclass jClass, const char* methodName, const char* methodType);
|
||||||
|
@ -312,9 +311,6 @@ protected:
|
||||||
// some convinient types to have around
|
// some convinient types to have around
|
||||||
jclass jStringClass;
|
jclass jStringClass;
|
||||||
|
|
||||||
jni::Object::GlobalRef mClassLoader;
|
|
||||||
jmethodID mClassLoaderLoadClass;
|
|
||||||
|
|
||||||
jni::Object::GlobalRef mMessageQueue;
|
jni::Object::GlobalRef mMessageQueue;
|
||||||
jfieldID mMessageQueueMessages;
|
jfieldID mMessageQueueMessages;
|
||||||
jmethodID mMessageQueueNext;
|
jmethodID mMessageQueueNext;
|
||||||
|
@ -337,11 +333,11 @@ private:
|
||||||
public:
|
public:
|
||||||
AutoJNIClass(JNIEnv* jEnv, const char* name)
|
AutoJNIClass(JNIEnv* jEnv, const char* name)
|
||||||
: mEnv(jEnv)
|
: mEnv(jEnv)
|
||||||
, mClass(AndroidBridge::GetClassGlobalRef(jEnv, name))
|
, mClass(jni::GetClassRef(jEnv, name))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~AutoJNIClass() {
|
~AutoJNIClass() {
|
||||||
mEnv->DeleteGlobalRef(mClass);
|
mEnv->DeleteLocalRef(mClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
jclass getRawRef() const {
|
jclass getRawRef() const {
|
||||||
|
|
|
@ -180,7 +180,9 @@ public:
|
||||||
jclass ClassRef() const
|
jclass ClassRef() const
|
||||||
{
|
{
|
||||||
if (!sClassRef) {
|
if (!sClassRef) {
|
||||||
sClassRef = GetClassGlobalRef(mEnv, Cls::name);
|
const jclass cls = GetClassRef(mEnv, Cls::name);
|
||||||
|
sClassRef = jclass(mEnv->NewGlobalRef(cls));
|
||||||
|
mEnv->DeleteLocalRef(cls);
|
||||||
}
|
}
|
||||||
return sClassRef;
|
return sClassRef;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
|
#include <android/log.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
|
|
||||||
#include "AndroidBridge.h"
|
|
||||||
#include "GeneratedJNIWrappers.h"
|
#include "GeneratedJNIWrappers.h"
|
||||||
#include "nsAppShell.h"
|
#include "nsAppShell.h"
|
||||||
|
|
||||||
|
@ -71,6 +71,8 @@ namespace {
|
||||||
JavaVM* sJavaVM;
|
JavaVM* sJavaVM;
|
||||||
pthread_key_t sThreadEnvKey;
|
pthread_key_t sThreadEnvKey;
|
||||||
jclass sOOMErrorClass;
|
jclass sOOMErrorClass;
|
||||||
|
jobject sClassLoader;
|
||||||
|
jmethodID sClassLoaderLoadClass;
|
||||||
|
|
||||||
void UnregisterThreadEnv(void* env)
|
void UnregisterThreadEnv(void* env)
|
||||||
{
|
{
|
||||||
|
@ -106,6 +108,12 @@ void SetGeckoThreadEnv(JNIEnv* aEnv)
|
||||||
sOOMErrorClass = Class::GlobalRef(Class::LocalRef::Adopt(
|
sOOMErrorClass = Class::GlobalRef(Class::LocalRef::Adopt(
|
||||||
aEnv->FindClass("java/lang/OutOfMemoryError"))).Forget();
|
aEnv->FindClass("java/lang/OutOfMemoryError"))).Forget();
|
||||||
aEnv->ExceptionClear();
|
aEnv->ExceptionClear();
|
||||||
|
|
||||||
|
sClassLoader = Object::GlobalRef(java::GeckoThread::ClsLoader()).Forget();
|
||||||
|
sClassLoaderLoadClass = aEnv->GetMethodID(
|
||||||
|
Class::LocalRef::Adopt(aEnv->GetObjectClass(sClassLoader)).Get(),
|
||||||
|
"loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
|
||||||
|
MOZ_ASSERT(sClassLoader && sClassLoaderLoadClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEnv* GetEnvForThread()
|
JNIEnv* GetEnvForThread()
|
||||||
|
@ -197,11 +205,11 @@ jfieldID sJNIObjectHandleField;
|
||||||
|
|
||||||
bool EnsureJNIObject(JNIEnv* env, jobject instance) {
|
bool EnsureJNIObject(JNIEnv* env, jobject instance) {
|
||||||
if (!sJNIObjectClass) {
|
if (!sJNIObjectClass) {
|
||||||
sJNIObjectClass = AndroidBridge::GetClassGlobalRef(
|
sJNIObjectClass = Class::GlobalRef(Class::LocalRef::Adopt(GetClassRef(
|
||||||
env, "org/mozilla/gecko/mozglue/JNIObject");
|
env, "org/mozilla/gecko/mozglue/JNIObject"))).Forget();
|
||||||
|
|
||||||
sJNIObjectHandleField = AndroidBridge::GetFieldID(
|
sJNIObjectHandleField = env->GetFieldID(
|
||||||
env, sJNIObjectClass, "mHandle", "J");
|
sJNIObjectClass, "mHandle", "J");
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(env->IsInstanceOf(instance, sJNIObjectClass));
|
MOZ_ASSERT(env->IsInstanceOf(instance, sJNIObjectClass));
|
||||||
|
@ -230,11 +238,33 @@ void SetNativeHandle(JNIEnv* env, jobject instance, uintptr_t handle)
|
||||||
static_cast<jlong>(handle));
|
static_cast<jlong>(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
jclass GetClassGlobalRef(JNIEnv* aEnv, const char* aClassName)
|
jclass GetClassRef(JNIEnv* aEnv, const char* aClassName)
|
||||||
{
|
{
|
||||||
return AndroidBridge::GetClassGlobalRef(aEnv, aClassName);
|
// First try the default class loader.
|
||||||
|
auto classRef = Class::LocalRef::Adopt(aEnv, aEnv->FindClass(aClassName));
|
||||||
|
|
||||||
|
if (!classRef && sClassLoader) {
|
||||||
|
// If the default class loader failed but we have an app class loader, try that.
|
||||||
|
// Clear the pending exception from failed FindClass call above.
|
||||||
|
aEnv->ExceptionClear();
|
||||||
|
classRef = Class::LocalRef::Adopt(aEnv, jclass(
|
||||||
|
aEnv->CallObjectMethod(sClassLoader, sClassLoaderLoadClass,
|
||||||
|
StringParam(aClassName, aEnv).Get())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (classRef) {
|
||||||
|
return classRef.Forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
__android_log_print(
|
||||||
|
ANDROID_LOG_ERROR, "Gecko",
|
||||||
|
">>> FATAL JNI ERROR! FindClass(className=\"%s\") failed. "
|
||||||
|
"Did ProGuard optimize away something it shouldn't have?",
|
||||||
|
aClassName);
|
||||||
|
aEnv->ExceptionDescribe();
|
||||||
|
MOZ_CRASH("Cannot find JNI class");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void DispatchToGeckoThread(UniquePtr<AbstractCall>&& aCall)
|
void DispatchToGeckoThread(UniquePtr<AbstractCall>&& aCall)
|
||||||
{
|
{
|
||||||
|
|
|
@ -125,8 +125,7 @@ uintptr_t GetNativeHandle(JNIEnv* env, jobject instance);
|
||||||
|
|
||||||
void SetNativeHandle(JNIEnv* env, jobject instance, uintptr_t handle);
|
void SetNativeHandle(JNIEnv* env, jobject instance, uintptr_t handle);
|
||||||
|
|
||||||
jclass GetClassGlobalRef(JNIEnv* aEnv, const char* aClassName);
|
jclass GetClassRef(JNIEnv* aEnv, const char* aClassName);
|
||||||
|
|
||||||
|
|
||||||
struct AbstractCall
|
struct AbstractCall
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче