/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Sun Microsystems, * Inc. Portions created by Sun are * Copyright (C) 1999 Sun Microsystems, Inc. All * Rights Reserved. * * Contributor(s): */ #include "PlugletEngine.h" #include "Pluglet.h" #include "nsIServiceManager.h" #include "prenv.h" #include "PlugletManager.h" #include "nsIGenericFactory.h" #include "nsIModule.h" #include "PlugletLog.h" #ifndef OJI_DISABLE #include "ProxyJNI.h" static NS_DEFINE_CID(kJVMManagerCID,NS_JVMMANAGER_CID); PlugletSecurityContext *PlugletEngine::securityContext = NULL; nsJVMManager * PlugletEngine::jvmManager = NULL; #endif /* OJI_DISABLE */ static NS_DEFINE_CID(kIPluginIID,NS_IPLUGIN_IID); static NS_DEFINE_CID(kPluginCID,NS_PLUGIN_CID); static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); static NS_DEFINE_CID(kPluginManagerCID, NS_PLUGINMANAGER_CID); PRLogModuleInfo* PlugletLog::log = NULL; #define PLUGLETENGINE_ContractID \ "@mozilla.org/blackwood/pluglet-engine;1" #define PLUGLETENGINE_CID \ { /* C1E694F3-9BE1-11d3-837C-0004AC56C49E */ \ 0xc1e694f3, 0x9be1, 0x11d3, { 0x83, 0x7c, 0x0, 0x4, 0xac, 0x56, 0xc4, 0x9e } \ } #ifdef XP_PC NS_GENERIC_FACTORY_CONSTRUCTOR(PlugletEngine) #else //XP_PC #include /* * CheckForXTSymbol * return value * 1 - AWT will not complain * 0 - AWT will not work * */ int CheckForXTSymbol(void) { Dl_info dlinfo; void *v; v = dlsym(RTLD_DEFAULT, "vendorShellWidgetClass"); if (v != NULL && dladdr(v, &dlinfo)) { if (strstr(dlinfo.dli_fname, "libXt.so") != NULL) { fprintf(stderr, "\nRuntime link error - it appears that " "libXt got loaded before libXm,\n" "which is not allowed for pluglets\n"); return 0; } } return 1; } static NS_IMETHODIMP PlugletEngineConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) { nsresult rv; PlugletEngine * inst; if ( !CheckForXTSymbol() ) { rv = NS_ERROR_FAILURE; return rv; } if (NULL == aResult) { rv = NS_ERROR_NULL_POINTER; return rv; } *aResult = NULL; if (NULL != aOuter) { rv = NS_ERROR_NO_AGGREGATION; return rv; } NS_NEWXPCOM(inst, PlugletEngine); if (NULL == inst) { rv = NS_ERROR_OUT_OF_MEMORY; return rv; } NS_ADDREF(inst); rv = inst->QueryInterface(aIID, aResult); NS_RELEASE(inst); return rv; } #endif //XP_PC static nsModuleComponentInfo components[] = { { "Pluglet Engine", PLUGLETENGINE_CID, PLUGLETENGINE_ContractID, PlugletEngineConstructor } }; NS_IMPL_NSGETMODULE("PlugletEngineModule",components); int PlugletEngine::objectCount = 0; PlugletsDir * PlugletEngine::dir = NULL; PRInt32 PlugletEngine::lockCount = 0; PlugletEngine * PlugletEngine::engine = NULL; nsCOMPtr PlugletEngine::pluginManager; jobject PlugletEngine::plugletManager = NULL; #define PLUGIN_MIME_DESCRIPTION "*:*:Pluglet Engine" NS_IMPL_ISUPPORTS(PlugletEngine,kIPluginIID); NS_METHOD PlugletEngine::Initialize(void) { //nb ??? return NS_OK; } NS_METHOD PlugletEngine::Shutdown(void) { //nb ??? return NS_OK; } NS_METHOD PlugletEngine::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult) { return NS_ERROR_FAILURE; //nb to do } NS_METHOD PlugletEngine::CreatePluginInstance(nsISupports *aOuter, REFNSIID aIID, const char* aPluginMIMEType, void **aResult) { PR_LOG(PlugletLog::log, PR_LOG_DEBUG, ("PlugletEngine::CreatePluginInstance\n")); if (!aResult) { return NS_ERROR_FAILURE; } PlugletFactory * plugletFactory = NULL; nsresult res = NS_ERROR_NULL_POINTER; if ((res = dir->GetPlugletFactory(aPluginMIMEType,&plugletFactory)) != NS_OK || !plugletFactory) { return res; } //we do not delete pluglet because we do not allocate new memory in dir->GetPluglet() return plugletFactory->CreatePluginInstance(aPluginMIMEType,aResult); } NS_METHOD PlugletEngine::GetMIMEDescription(const char* *result) { PR_LOG(PlugletLog::log, PR_LOG_DEBUG, ("PlugletEngine::GetMimeDescription\n")); if (!result) { return NS_ERROR_FAILURE; } *result = PLUGIN_MIME_DESCRIPTION; return NS_OK; } NS_METHOD PlugletEngine::GetValue(nsPluginVariable variable, void *value) { PR_LOG(PlugletLog::log, PR_LOG_DEBUG, ("PlugletEngine::GetValue; stub\n")); //nb ???? return NS_OK; } NS_METHOD PlugletEngine::LockFactory(PRBool aLock) { if(aLock) { PR_AtomicIncrement(&lockCount); } else { PR_AtomicDecrement(&lockCount); } return NS_OK; } char *ToString(jobject obj,JNIEnv *env) { static jmethodID toStringID = NULL; if (!toStringID) { jclass clazz = env->FindClass("java/lang/Object"); toStringID = env->GetMethodID(clazz,"toString","()Ljava/lang/String;"); } jstring jstr = (jstring) env->CallObjectMethod(obj,toStringID); const char * str = NULL; str = env->GetStringUTFChars(jstr,NULL); char * res = new char[strlen(str)]; strcpy(res,str); env->ReleaseStringUTFChars(jstr,str); return res; } PlugletEngine::PlugletEngine() { NS_INIT_REFCNT(); PlugletLog::log = PR_NewLogModule("pluglets"); dir = new PlugletsDir(); engine = this; objectCount++; } PlugletEngine::~PlugletEngine(void) { delete dir; objectCount--; } #ifdef OJI_DISABLE #ifdef XP_PC #define PATH_SEPARATOR ';' #else /* XP_PC */ #define PATH_SEPARATOR ':' #endif /* XP_PC */ JavaVM *PlugletEngine::jvm = NULL; void PlugletEngine::StartJVM() { JNIEnv *env = NULL; jint res; jsize jvmCount; JNI_GetCreatedJavaVMs(&jvm, 1, &jvmCount); if (jvmCount) { PR_LOG(PlugletLog::log, PR_LOG_DEBUG, ("PlugletEngine::StartJVM we got already started JVM\n")); return; } char classpath[1024]=""; JavaVMInitArgs vm_args; JavaVMOption options[2]; char * classpathEnv = PR_GetEnv("CLASSPATH"); if (classpathEnv != NULL) { sprintf(classpath, "-Djava.class.path=%s",classpathEnv); PR_LOG(PlugletLog::log, PR_LOG_DEBUG, ("PlugletEngine::StartJVM about to create JVM classpath=%s\n",classpath)); } options[0].optionString = classpath; options[1].optionString=""; //-Djava.compiler=NONE"; vm_args.version = 0x00010002; vm_args.options = options; vm_args.nOptions = 2; vm_args.ignoreUnrecognized = JNI_TRUE; /* Create the Java VM */ res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); printf("--bcJavaGlobal::StartJVM jvm started res %d\n",res); PR_LOG(PlugletLog::log, PR_LOG_DEBUG, ("PlugletEngine::StartJVM after CreateJavaVM res = %d\n",res)); } #endif /* OJI_DISABLE */ JNIEnv * PlugletEngine::GetJNIEnv(void) { JNIEnv * res = NULL; #ifndef OJI_DISABLE nsresult result; if (!jvmManager) { NS_WITH_SERVICE(nsIJVMManager, _jvmManager, kJVMManagerCID, &result); if (NS_SUCCEEDED(result)) { jvmManager = (nsJVMManager*)((nsIJVMManager*)_jvmManager); } } if (!jvmManager) { return NULL; } if (NS_FAILED(jvmManager->CreateProxyJNI(NULL,&res))) { return NULL; } if (!securityContext) { securityContext = new PlugletSecurityContext(); } SetSecurityContext(res,securityContext); #else /* OJI_DISABLE */ if (!jvm) { PR_LOG(PlugletLog::log, PR_LOG_DEBUG, ("PlugletEngine::GetJNIEnv going to start our own jvm \n")); StartJVM(); } if (jvm) { jvm->AttachCurrentThread((void**)&res,NULL); } #endif /* OJI_DISABLE */ return res; } jobject PlugletEngine::GetPlugletManager(void) { PR_LOG(PlugletLog::log, PR_LOG_DEBUG, ("PlugletEngine::GetPlugletManager\n")); if (!pluginManager) { nsresult res; NS_WITH_SERVICE(nsIPluginManager,_pluginManager,kPluginManagerCID,&res); if (NS_SUCCEEDED(res)) { pluginManager = _pluginManager; } } if (!pluginManager) { return NULL; } if (!plugletManager) { plugletManager = PlugletManager::GetJObject(pluginManager.get()); } return plugletManager; } PlugletEngine * PlugletEngine::GetEngine(void) { return engine; } void PlugletEngine::IncObjectCount(void) { objectCount++; } void PlugletEngine::DecObjectCount(void) { objectCount--; } PRBool PlugletEngine::IsUnloadable(void) { return (lockCount == 0 && objectCount == 0); }