fix for 77579 r=yiming.chung@eng.sun.com git-svn-id: svn://10.0.0.236/trunk@96227 18797224-902f-48f8-a5cc-f745e15eee43
345 lines
10 KiB
C++
345 lines
10 KiB
C++
/* -*- 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 <dlfcn.h>
|
|
|
|
/*
|
|
* 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<nsIPluginManager> 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);
|
|
}
|
|
|