diff --git a/mozilla/extensions/java/xpcom/GeckoEmbed.java b/mozilla/extensions/java/xpcom/GeckoEmbed.java index f8b0faf7770..b43bc26d0fe 100644 --- a/mozilla/extensions/java/xpcom/GeckoEmbed.java +++ b/mozilla/extensions/java/xpcom/GeckoEmbed.java @@ -40,7 +40,7 @@ package org.mozilla.xpcom; public final class GeckoEmbed { // XPCOM Utility functions - public static native void NS_InitEmbedding(String aMozBinDirectory, int aAppFileLocProvider); + public static native void NS_InitEmbedding(nsILocalFile aMozBinDirectory, nsISupports aAppFileLocProvider); public static native void NS_TermEmbedding(); public static native nsILocalFile NS_NewLocalFile(String aPath, boolean followLinks); public static native nsIComponentManager NS_GetComponentManager(); diff --git a/mozilla/extensions/java/xpcom/nsJavaInterfaces.cpp b/mozilla/extensions/java/xpcom/nsJavaInterfaces.cpp index 6abe63d14b0..7824b254bab 100644 --- a/mozilla/extensions/java/xpcom/nsJavaInterfaces.cpp +++ b/mozilla/extensions/java/xpcom/nsJavaInterfaces.cpp @@ -51,8 +51,8 @@ PRBool gEmbeddingInitialized = PR_FALSE; extern "C" JNIEXPORT void JNICALL -XPCOM_NATIVE(NS_1InitEmbedding) (JNIEnv* env, jclass, jstring aMozBinDirectory, - jint aAppFileLocProvider) +XPCOM_NATIVE(NS_1InitEmbedding) (JNIEnv* env, jclass, jobject aMozBinDirectory, + jobject aAppFileLocProvider) { if (!InitializeJavaGlobals(env)) { FreeJavaGlobals(env); @@ -64,14 +64,16 @@ XPCOM_NATIVE(NS_1InitEmbedding) (JNIEnv* env, jclass, jstring aMozBinDirectory, nsCOMPtr directory; if (aMozBinDirectory) { - jboolean isCopy; - const PRUnichar* buf = env->GetStringChars(aMozBinDirectory, &isCopy); - nsAutoString path(buf); - rv = NS_NewLocalFile(path, PR_TRUE, getter_AddRefs(directory)); - if (NS_FAILED(rv)) { - ThrowXPCOMException(env, rv); + // Find corresponding XPCOM object + void* xpcomObj = GetMatchingXPCOMObject(env, aMozBinDirectory); + NS_ASSERTION(xpcomObj != nsnull, "Failed to get matching XPCOM object"); + if (xpcomObj == nsnull) { + ThrowXPCOMException(env, 0); return; } + + NS_ASSERTION(!IsXPTCStub(xpcomObj), "Expected JavaXPCOMInstance, but got nsJavaXPTCStub"); + directory = do_QueryInterface(((JavaXPCOMInstance*) xpcomObj)->GetInstance()); } /* XXX How do we handle AppFileLocProvider, if we can't create any of the @@ -112,14 +114,14 @@ extern "C" JNIEXPORT jobject JNICALL XPCOM_NATIVE(NS_1NewLocalFile) (JNIEnv *env, jclass, jstring aPath, jboolean aFollowLinks) { - jobject java_stub = nsnull; - - // XXX For now, return if we haven't called NS_InitEmbedding yet - if (!gEmbeddingInitialized) { + if (!InitializeJavaGlobals(env)) { + FreeJavaGlobals(env); ThrowXPCOMException(env, 0); return nsnull; } + jobject java_stub = nsnull; + // Create a Mozilla string from the jstring jboolean isCopy; const PRUnichar* buf = nsnull; @@ -139,7 +141,7 @@ XPCOM_NATIVE(NS_1NewLocalFile) (JNIEnv *env, jclass, jstring aPath, if (NS_SUCCEEDED(rv)) { // wrap xpcom instance JavaXPCOMInstance* inst; - inst = CreateJavaXPCOMInstance(file, &NS_GET_IID(nsILocalFile)); + inst = CreateJavaXPCOMInstance(file, nsnull); if (inst) { // create java stub diff --git a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp index 54e08bfa13a..4b639d34d2c 100644 --- a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp +++ b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp @@ -41,8 +41,13 @@ #include "jni.h" #include "nsIInterfaceInfoManager.h" #include "pldhash.h" +#include "nsILocalFile.h" +#ifdef DEBUG +extern PRBool gEmbeddingInitialized; +#endif + /* Java JNI globals */ jclass classClass = nsnull; jmethodID getNameMID = nsnull; @@ -247,195 +252,201 @@ GetMatchingJavaObject(JNIEnv* env, void* aXPCOMObject) PRBool InitializeJavaGlobals(JNIEnv *env) { - jclass clazz; - if (!(clazz = env->FindClass("java/lang/Class")) || - !(classClass = (jclass) env->NewGlobalRef(clazz))) + static PRBool initialized = PR_FALSE; + if (!initialized) { + jclass clazz; + if (!(clazz = env->FindClass("java/lang/Class")) || + !(classClass = (jclass) env->NewGlobalRef(clazz))) + { + return PR_FALSE; + } + + if (!(clazz = env->FindClass("java/lang/Object")) || + !(objectClass = (jclass) env->NewGlobalRef(clazz))) + { + return PR_FALSE; + } + + if (!(clazz = env->FindClass("java/lang/Boolean")) || + !(booleanClass = (jclass) env->NewGlobalRef(clazz)) || + !(clazz = env->FindClass("[Z")) || + !(booleanArrayClass = (jclass) env->NewGlobalRef(clazz))) + { + return PR_FALSE; + } + + if (!(clazz = env->FindClass("java/lang/Character")) || + !(charClass = (jclass) env->NewGlobalRef(clazz)) || + !(clazz = env->FindClass("[C")) || + !(charArrayClass = (jclass) env->NewGlobalRef(clazz))) + { + return PR_FALSE; + } + if (!(clazz = env->FindClass("java/lang/Byte")) || + !(byteClass = (jclass) env->NewGlobalRef(clazz)) || + !(clazz = env->FindClass("[B")) || + !(byteArrayClass = (jclass) env->NewGlobalRef(clazz))) + { + return PR_FALSE; + } + if (!(clazz = env->FindClass("java/lang/Short")) || + !(shortClass = (jclass) env->NewGlobalRef(clazz)) || + !(clazz = env->FindClass("[[S")) || + !(shortArrayClass = (jclass) env->NewGlobalRef(clazz))) + { + return PR_FALSE; + } + if (!(clazz = env->FindClass("java/lang/Integer")) || + !(intClass = (jclass) env->NewGlobalRef(clazz)) || + !(clazz = env->FindClass("[I")) || + !(intArrayClass = (jclass) env->NewGlobalRef(clazz))) + { + return PR_FALSE; + } + if (!(clazz = env->FindClass("java/lang/Long")) || + !(longClass = (jclass) env->NewGlobalRef(clazz)) || + !(clazz = env->FindClass("[J"))) + { + return PR_FALSE; + } + if (!(clazz = env->FindClass("java/lang/Float")) || + !(floatClass = (jclass) env->NewGlobalRef(clazz)) || + !(clazz = env->FindClass("[F")) || + !(floatArrayClass = (jclass) env->NewGlobalRef(clazz))) + { + return PR_FALSE; + } + if (!(clazz = env->FindClass("java/lang/Double")) || + !(doubleClass = (jclass) env->NewGlobalRef(clazz)) || + !(clazz = env->FindClass("[D")) || + !(doubleArrayClass = (jclass) env->NewGlobalRef(clazz))) + { + return PR_FALSE; + } + + if (!(clazz = env->FindClass("java/lang/String")) || + !(stringClass = (jclass) env->NewGlobalRef(clazz)) || + !(clazz = env->FindClass("[Ljava/lang/String;")) || + !(stringArrayClass = (jclass) env->NewGlobalRef(clazz))) + { + return PR_FALSE; + } + + if (!(clazz = env->FindClass("org/mozilla/xpcom/nsISupports")) || + !(nsISupportsClass = (jclass) env->NewGlobalRef(clazz))) + { + return PR_FALSE; + } + + if (!(clazz = env->FindClass("java/lang/Exception")) || + !(exceptionClass = (jclass) env->NewGlobalRef(clazz))) + { + return PR_FALSE; + } + + if (!(hashCodeMID = env->GetMethodID(objectClass, "hashCode","()I"))) { + return PR_FALSE; + } + + if (!(booleanInitMID = env->GetMethodID(booleanClass,"","(Z)V"))) { + return PR_FALSE; + } + if (!(booleanValueMID = env->GetMethodID(booleanClass,"booleanValue","()Z"))) { + return PR_FALSE; + } + + if (!(charInitMID = env->GetMethodID(charClass,"","(C)V"))) { + return PR_FALSE; + } + if (!(charValueMID = env->GetMethodID(charClass,"charValue","()C"))) { + return PR_FALSE; + } + + if (!(byteInitMID = env->GetMethodID(byteClass,"","(B)V"))) { + return PR_FALSE; + } + if (!(byteValueMID = env->GetMethodID(byteClass,"byteValue","()B"))) { + return PR_FALSE; + } + if (!(shortInitMID = env->GetMethodID(shortClass,"","(S)V"))) { + return PR_FALSE; + } + if (!(shortValueMID = env->GetMethodID(shortClass,"shortValue","()S"))) { + return PR_FALSE; + } + + if (!(intInitMID = env->GetMethodID(intClass,"","(I)V"))) { + return PR_FALSE; + } + if (!(intValueMID = env->GetMethodID(intClass,"intValue","()I"))) { + return PR_FALSE; + } + + if (!(longInitMID = env->GetMethodID(longClass,"","(J)V"))) { + return PR_FALSE; + } + if (!(longValueMID = env->GetMethodID(longClass,"longValue","()J"))) { + return PR_FALSE; + } + + if (!(floatInitMID = env->GetMethodID(floatClass,"","(F)V"))) { + return PR_FALSE; + } + if (!(floatValueMID = env->GetMethodID(floatClass,"floatValue","()F"))) { + return PR_FALSE; + } + + if (!(doubleInitMID = env->GetMethodID(doubleClass,"","(D)V"))) { + return PR_FALSE; + } + if (!(doubleValueMID = env->GetMethodID(doubleClass,"doubleValue","()D"))) { + return PR_FALSE; + } + + if (!(getNameMID = env->GetMethodID(classClass, "getName","()Ljava/lang/String;"))) { + return PR_FALSE; + } + + static PLDHashTableOps java_to_xpcom_hash_ops = + { + PL_DHashAllocTable, + PL_DHashFreeTable, + PL_DHashGetKeyStub, + PL_DHashVoidPtrKeyStub, + PL_DHashMatchEntryStub, + PL_DHashMoveEntryStub, + PL_DHashClearEntryStub, + PL_DHashFinalizeStub, + InitJAVAtoXPCOMBindingEntry + }; + + gJAVAtoXPCOMBindings = PL_NewDHashTable(&java_to_xpcom_hash_ops, nsnull, + sizeof(JavaXPCOMBindingEntry), 16); + if (!gJAVAtoXPCOMBindings) { return PR_FALSE; - } + } + + static PLDHashTableOps xpcom_to_java_hash_ops = + { + PL_DHashAllocTable, + PL_DHashFreeTable, + PL_DHashGetKeyStub, + PL_DHashVoidPtrKeyStub, + PL_DHashMatchEntryStub, + PL_DHashMoveEntryStub, + PL_DHashClearEntryStub, + PL_DHashFinalizeStub, + InitXPCOMtoJAVABindingEntry + }; + + gXPCOMtoJAVABindings = PL_NewDHashTable(&xpcom_to_java_hash_ops, nsnull, + sizeof(JavaXPCOMBindingEntry), 16); + if (!gXPCOMtoJAVABindings) { + return PR_FALSE; + } - if (!(clazz = env->FindClass("java/lang/Object")) || - !(objectClass = (jclass) env->NewGlobalRef(clazz))) - { - return PR_FALSE; - } - - if (!(clazz = env->FindClass("java/lang/Boolean")) || - !(booleanClass = (jclass) env->NewGlobalRef(clazz)) || - !(clazz = env->FindClass("[Z")) || - !(booleanArrayClass = (jclass) env->NewGlobalRef(clazz))) - { - return PR_FALSE; - } - - if (!(clazz = env->FindClass("java/lang/Character")) || - !(charClass = (jclass) env->NewGlobalRef(clazz)) || - !(clazz = env->FindClass("[C")) || - !(charArrayClass = (jclass) env->NewGlobalRef(clazz))) - { - return PR_FALSE; - } - if (!(clazz = env->FindClass("java/lang/Byte")) || - !(byteClass = (jclass) env->NewGlobalRef(clazz)) || - !(clazz = env->FindClass("[B")) || - !(byteArrayClass = (jclass) env->NewGlobalRef(clazz))) - { - return PR_FALSE; - } - if (!(clazz = env->FindClass("java/lang/Short")) || - !(shortClass = (jclass) env->NewGlobalRef(clazz)) || - !(clazz = env->FindClass("[[S")) || - !(shortArrayClass = (jclass) env->NewGlobalRef(clazz))) - { - return PR_FALSE; - } - if (!(clazz = env->FindClass("java/lang/Integer")) || - !(intClass = (jclass) env->NewGlobalRef(clazz)) || - !(clazz = env->FindClass("[I")) || - !(intArrayClass = (jclass) env->NewGlobalRef(clazz))) - { - return PR_FALSE; - } - if (!(clazz = env->FindClass("java/lang/Long")) || - !(longClass = (jclass) env->NewGlobalRef(clazz)) || - !(clazz = env->FindClass("[J"))) - { - return PR_FALSE; - } - if (!(clazz = env->FindClass("java/lang/Float")) || - !(floatClass = (jclass) env->NewGlobalRef(clazz)) || - !(clazz = env->FindClass("[F")) || - !(floatArrayClass = (jclass) env->NewGlobalRef(clazz))) - { - return PR_FALSE; - } - if (!(clazz = env->FindClass("java/lang/Double")) || - !(doubleClass = (jclass) env->NewGlobalRef(clazz)) || - !(clazz = env->FindClass("[D")) || - !(doubleArrayClass = (jclass) env->NewGlobalRef(clazz))) - { - return PR_FALSE; - } - - if (!(clazz = env->FindClass("java/lang/String")) || - !(stringClass = (jclass) env->NewGlobalRef(clazz)) || - !(clazz = env->FindClass("[Ljava/lang/String;")) || - !(stringArrayClass = (jclass) env->NewGlobalRef(clazz))) - { - return PR_FALSE; - } - - if (!(clazz = env->FindClass("org/mozilla/xpcom/nsISupports")) || - !(nsISupportsClass = (jclass) env->NewGlobalRef(clazz))) - { - return PR_FALSE; - } - - if (!(clazz = env->FindClass("java/lang/Exception")) || - !(exceptionClass = (jclass) env->NewGlobalRef(clazz))) - { - return PR_FALSE; - } - - if (!(hashCodeMID = env->GetMethodID(objectClass, "hashCode","()I"))) { - return PR_FALSE; - } - - if (!(booleanInitMID = env->GetMethodID(booleanClass,"","(Z)V"))) { - return PR_FALSE; - } - if (!(booleanValueMID = env->GetMethodID(booleanClass,"booleanValue","()Z"))) { - return PR_FALSE; - } - - if (!(charInitMID = env->GetMethodID(charClass,"","(C)V"))) { - return PR_FALSE; - } - if (!(charValueMID = env->GetMethodID(charClass,"charValue","()C"))) { - return PR_FALSE; - } - - if (!(byteInitMID = env->GetMethodID(byteClass,"","(B)V"))) { - return PR_FALSE; - } - if (!(byteValueMID = env->GetMethodID(byteClass,"byteValue","()B"))) { - return PR_FALSE; - } - if (!(shortInitMID = env->GetMethodID(shortClass,"","(S)V"))) { - return PR_FALSE; - } - if (!(shortValueMID = env->GetMethodID(shortClass,"shortValue","()S"))) { - return PR_FALSE; - } - - if (!(intInitMID = env->GetMethodID(intClass,"","(I)V"))) { - return PR_FALSE; - } - if (!(intValueMID = env->GetMethodID(intClass,"intValue","()I"))) { - return PR_FALSE; - } - - if (!(longInitMID = env->GetMethodID(longClass,"","(J)V"))) { - return PR_FALSE; - } - if (!(longValueMID = env->GetMethodID(longClass,"longValue","()J"))) { - return PR_FALSE; - } - - if (!(floatInitMID = env->GetMethodID(floatClass,"","(F)V"))) { - return PR_FALSE; - } - if (!(floatValueMID = env->GetMethodID(floatClass,"floatValue","()F"))) { - return PR_FALSE; - } - - if (!(doubleInitMID = env->GetMethodID(doubleClass,"","(D)V"))) { - return PR_FALSE; - } - if (!(doubleValueMID = env->GetMethodID(doubleClass,"doubleValue","()D"))) { - return PR_FALSE; - } - - if (!(getNameMID = env->GetMethodID(classClass, "getName","()Ljava/lang/String;"))) { - return PR_FALSE; - } - - static PLDHashTableOps java_to_xpcom_hash_ops = - { - PL_DHashAllocTable, - PL_DHashFreeTable, - PL_DHashGetKeyStub, - PL_DHashVoidPtrKeyStub, - PL_DHashMatchEntryStub, - PL_DHashMoveEntryStub, - PL_DHashClearEntryStub, - PL_DHashFinalizeStub, - InitJAVAtoXPCOMBindingEntry - }; - - gJAVAtoXPCOMBindings = PL_NewDHashTable(&java_to_xpcom_hash_ops, nsnull, - sizeof(JavaXPCOMBindingEntry), 16); - if (!gJAVAtoXPCOMBindings) { - return PR_FALSE; - } - - static PLDHashTableOps xpcom_to_java_hash_ops = - { - PL_DHashAllocTable, - PL_DHashFreeTable, - PL_DHashGetKeyStub, - PL_DHashVoidPtrKeyStub, - PL_DHashMatchEntryStub, - PL_DHashMoveEntryStub, - PL_DHashClearEntryStub, - PL_DHashFinalizeStub, - InitXPCOMtoJAVABindingEntry - }; - - gXPCOMtoJAVABindings = PL_NewDHashTable(&xpcom_to_java_hash_ops, nsnull, - sizeof(JavaXPCOMBindingEntry), 16); - if (!gXPCOMtoJAVABindings) { - return PR_FALSE; + initialized = PR_TRUE; } return PR_TRUE; @@ -454,22 +465,48 @@ FreeJavaGlobals(JNIEnv* env) /********************************************************** * JavaXPCOMInstance *********************************************************/ +nsIInterfaceInfo* +JavaXPCOMInstance::InterfaceInfo() +{ + // We lazily create the interfaceInfo for nsILocalFile. + if (!mIInfo) { + NS_ASSERTION(gEmbeddingInitialized, "Trying to create interface info, but XPCOM not inited"); + + // Get interface info for class + nsCOMPtr iim = XPTI_GetInterfaceInfoManager(); + NS_ASSERTION(iim != nsnull, "Failed to get InterfaceInfoManager"); + if (iim) { + iim->GetInfoForIID(&NS_GET_IID(nsILocalFile), getter_AddRefs(mIInfo)); + } + } + + NS_ASSERTION(mIInfo, "No interfaceInfo for JavaXPCOMInstance"); + return mIInfo; +} + JavaXPCOMInstance* CreateJavaXPCOMInstance(nsISupports* aXPCOMObject, const nsIID* aIID) { JavaXPCOMInstance* inst = nsnull; - // Get interface info for class - nsCOMPtr iim = XPTI_GetInterfaceInfoManager(); - NS_ASSERTION(iim != nsnull, "Failed to get InterfaceInfoManager"); - if (iim) { - nsCOMPtr info; - iim->GetInfoForIID(aIID, getter_AddRefs(info)); + // We can't call XPTI_GetInterfaceInfoManager() before NS_InitEmbedding(), + // so for NS_NewLocalFile (which can be called before NS_InitEmbedding), we + // pass in a null aIID, and create the interface info lazily later. + if (!aIID) { + inst = new JavaXPCOMInstance(aXPCOMObject, nsnull); + } else { + // Get interface info for class + nsCOMPtr iim = XPTI_GetInterfaceInfoManager(); + NS_ASSERTION(iim != nsnull, "Failed to get InterfaceInfoManager"); + if (iim) { + nsCOMPtr info; + iim->GetInfoForIID(aIID, getter_AddRefs(info)); - // Wrap XPCOM object - inst = new JavaXPCOMInstance(aXPCOMObject, info); - NS_ADDREF(aXPCOMObject); + // Wrap XPCOM object + inst = new JavaXPCOMInstance(aXPCOMObject, info); + } } + NS_ADDREF(aXPCOMObject); return inst; } diff --git a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h index 26c3b14e01a..292cb994706 100644 --- a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h +++ b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h @@ -121,7 +121,7 @@ public: {} nsISupports* GetInstance() { return mInstance; } - nsIInterfaceInfo* InterfaceInfo() { return mIInfo; } + nsIInterfaceInfo* InterfaceInfo(); private: nsCOMPtr mInstance; @@ -131,6 +131,7 @@ private: JavaXPCOMInstance* CreateJavaXPCOMInstance(nsISupports* aXPCOMObject, const nsIID* aIID); + /************************************** * Java<->XPCOM binding stores **************************************/