Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Functions | Variables
CSecureEnv.cpp File Reference
#include "CSecureEnv.h"
#include "nsISecurityContext.h"
#include "MRJPlugin.h"
#include "MRJSession.h"
#include "nsIThreadManager.h"
#include "nsIJVMManager.h"
#include "nsIScriptSecurityManager.h"
#include "nsIPrincipal.h"
#include "MRJMonitor.h"
#include "NativeMonitor.h"
#include "JavaMessageQueue.h"

Go to the source code of this file.

Classes

class  CreateNativeThreadMessage
 Creates a new native thread in MRJ's main thread, to avoid deadlock problems. More...
class  NewObjectMessage
class  CallMethodMessage
class  CallNonvirtualMethodMessage
class  GetFieldMessage
class  SetFieldMessage
class  CallStaticMethodMessage
class  GetStaticFieldMessage
class  SetStaticFieldMessage
class  DefineClassMessage
 To give proper "local" refs, need to run this in the Java thread. More...
class  FindClassMessage
 To give proper "local" refs, need to run this in the Java thread. More...
class  GetSuperclassMessage
 To give proper "local" refs, need to run this in the Java thread. More...
class  IsAssignableFromMessage
class  ThrowMessage
class  ThrowNewMessage
class  ExceptionOccurredMessage
class  ExceptionClearMessage
class  NewGlobalRefMessage
 To give proper "local" refs, need to run this in the true thread. More...
class  DeleteLocalRefMessage
 To give proper "local" refs, need to run this in the true thread. More...
class  IsSameObjectMessage
class  AllocObjectMessage
class  GetObjectClassMessage
class  IsInstanceOfMessage
class  GetMethodIDMessage
class  GetFieldIDMessage
class  NewStringMessage
 To give proper "local" refs, need to run this in the true thread. More...
class  GetStringLengthMessage
class  GetStringCharsMessage
class  ReleaseStringCharsMessage
class  NewStringUTFMessage
class  GetStringUTFLengthMessage
class  GetStringUTFCharsMessage
class  ReleaseStringUTFCharsMessage
class  GetArrayLengthMessage
class  NewObjectArrayMessage
class  GetObjectArrayElementMessage
class  SetObjectArrayElementMessage
class  NewArrayMessage
class  GetArrayElementsMessage
class  ReleaseArrayElementsMessage
class  GetArrayRegionMessage
class  SetArrayRegionMessage
class  RegisterNativesMessage
class  UnregisterNativesMessage
class  MonitorEnterMessage
class  MonitorExitMessage

Defines

#define PROXY_JNI_CALLS   1
#define USE_LIVECONNECT_PROXY   1
#define LOCAL_REFS_ARE_GLOBAL   USE_LIVECONNECT_PROXY

Functions

jobject ToGlobalRef (JNIEnv *env, jobject localRef)
static void netscape_oji_JNIThread_run (JNIEnv *env, jobject self)
 Native run method that communicates with LiveConnect from a Java thread.
static void netscape_oji_JNIRunnable_run (JNIEnv *env, jobject self)
static bool check_exceptions (JNIEnv *env)
static void CreateJNIThread (CSecureEnv *secureEnv)
 Called from browser side, starts the Java thread that calls from LiveConnect to Java are processed in.
static jobject CreateJNIRunnable (JNIEnv *env, JavaMessage *msg)
static jclass GetLiveConnectProxy (JNIEnv *env, nsIPrincipal *codebasePrincipal)
static void CreateNativeThread (CSecureEnv *secureEnv)
 Called from a Java thread that wants to communicate with the browser.
CSecureEnvGetSecureJNI (JNIEnv *env, jobject thread)
 Returns the secure JNI associated with the current thread (if any).

Variables

static jclass netscape_oji_JNIRunnable
static jmethodID netscape_oji_JNIRunnable_constructorID
static jfieldID netscape_oji_JNIRunnable_mJavaMessageID

Define Documentation

Definition at line 54 of file CSecureEnv.cpp.

Definition at line 52 of file CSecureEnv.cpp.

Definition at line 53 of file CSecureEnv.cpp.


Function Documentation

static bool check_exceptions ( JNIEnv env) [static]

Definition at line 183 of file CSecureEnv.cpp.

{
    jthrowable exc = env->ExceptionOccurred();
       if (exc) {
           env->ExceptionDescribe();
           env->ExceptionClear();
           env->DeleteLocalRef(exc);
           return true;
       }
       return false;
}

Here is the caller graph for this function:

static jobject CreateJNIRunnable ( JNIEnv env,
JavaMessage msg 
) [static]

Definition at line 231 of file CSecureEnv.cpp.

{
    // XXX:  does this have to be thread safe?
    if (!netscape_oji_JNIRunnable) {
       jclass clazz = env->FindClass("netscape.oji.JNIRunnable");
       if (!clazz) return NULL;
              JNINativeMethod method = { "run", "()V", &netscape_oji_JNIRunnable_run };
              env->RegisterNatives(clazz, &method, 1);
              netscape_oji_JNIRunnable_constructorID = env->GetMethodID(clazz, "<init>", "(I)V");
        netscape_oji_JNIRunnable_mJavaMessageID = env->GetFieldID(clazz, "mJavaMessage", "I");
              netscape_oji_JNIRunnable = (jclass) env->NewGlobalRef(clazz);
              env->DeleteLocalRef(clazz);
    }
    check_exceptions(env);
    return env->NewObject(netscape_oji_JNIRunnable, netscape_oji_JNIRunnable_constructorID, msg);
}

Here is the call graph for this function:

static void CreateJNIThread ( CSecureEnv secureEnv) [static]

Called from browser side, starts the Java thread that calls from LiveConnect to Java are processed in.

Definition at line 199 of file CSecureEnv.cpp.

{
       nsIThreadManager* manager = secureEnv->getThreadManager();
       MRJSession* session = secureEnv->getSession();
       JNIEnv* env = session->getCurrentEnv();
       
    check_exceptions(env);

       jclass JNIThreadClass = env->FindClass("netscape.oji.JNIThread");
       if (JNIThreadClass != NULL) {
              JNINativeMethod method = { "run", "()V", &netscape_oji_JNIThread_run };
              env->RegisterNatives(JNIThreadClass, &method, 1);
              jmethodID constructorID = env->GetMethodID(JNIThreadClass, "<init>", "(I)V");
              if (constructorID != NULL) {
                     jobject javaThread = env->NewObject(JNIThreadClass, constructorID, secureEnv);
                     for (;;) {
                            // was there some kind of exception? bail if so.
                            if (check_exceptions(env))
                                break;
                            // give time to Java, to allow the thread to come up.
                            session->idle();
                            // has the thread made contact?
                            if (secureEnv->isInitialized())
                                   break;
                            // give time to NSPR, to avoid hanging too long.
                            manager->Sleep();
                     }
              }
              env->DeleteLocalRef(JNIThreadClass);
       }
}

Here is the call graph for this function:

static void CreateNativeThread ( CSecureEnv secureEnv) [static]

Called from a Java thread that wants to communicate with the browser.

Definition at line 312 of file CSecureEnv.cpp.

{
       nsresult result;
       PRUint32 threadID;
       MRJSession* session = secureEnv->getSession();
       
       // cause a native thread to be created on our behalf. Perhaps this should be a message we send to the
       // session itself. otherwise we could have reentrancy problems.
       CreateNativeThreadMessage message(&result, &threadID, secureEnv);
       session->sendMessage(&message);

       if (session->onMainThread()) {
              // give time to other native threads, so the new thread can come up.
              nsIThreadManager* manager = secureEnv->getThreadManager();
              while (!secureEnv->isInitialized()) {
                     manager->Sleep();
              }
       } else {
              // sleep the current Java thread until we rendezvous with the Native thread.
              JNIEnv* env = session->getCurrentEnv();
              jclass threadClass = env->FindClass("java/lang/Thread");
              if (threadClass != NULL) {
                     jmethodID sleepMethod = env->GetStaticMethodID(threadClass, "sleep", "(J)V");
                     if (sleepMethod != NULL) {
                            while (!secureEnv->isInitialized())
                                   env->CallStaticVoidMethod(threadClass, sleepMethod, jlong(1024));
                     }
                     env->DeleteLocalRef(threadClass);
              }
       }
}

Here is the call graph for this function:

static jclass GetLiveConnectProxy ( JNIEnv env,
nsIPrincipal codebasePrincipal 
) [static]

Definition at line 248 of file CSecureEnv.cpp.

{
    jclass liveConnectProxy = NULL;
    jclass netscape_oji_ProxyClassLoaderFactory = env->FindClass("netscape/oji/ProxyClassLoaderFactory");
    if (netscape_oji_ProxyClassLoaderFactory) {
        jmethodID createClassLoaderID = env->GetStaticMethodID(netscape_oji_ProxyClassLoaderFactory,
                                                               "createClassLoader", 
                                                               "(Ljava/lang/String;)Ljava/lang/ClassLoader;");
        if (createClassLoaderID) {
            jstring codebaseUTF = NULL;
            char* codebase;
            nsresult rv = codebasePrincipal->GetOrigin(&codebase);
            if (NS_SUCCEEDED(rv)) {
                codebaseUTF = env->NewStringUTF(codebase);
                delete[] codebase;
            }
            if (codebaseUTF) {
                jobject classLoader = env->CallStaticObjectMethod(netscape_oji_ProxyClassLoaderFactory,
                                                                  createClassLoaderID, codebaseUTF);
                if (classLoader) {
                    jclass clazz = env->GetObjectClass(classLoader);
                    jmethodID loadClassID = env->GetMethodID(clazz, "loadClass",
                                                             "(Ljava/lang/String;)Ljava/lang/Class;");
                    if (loadClassID) {
                        jstring className = env->NewStringUTF("netscape.oji.LiveConnectProxy");
                        if (className) {
                            liveConnectProxy = (jclass) env->CallObjectMethod(classLoader, loadClassID, className);
                            env->DeleteLocalRef(className);
                        }
                    }
                    env->DeleteLocalRef(clazz);
                }
                env->DeleteLocalRef(codebaseUTF);
            }
        }
        env->DeleteLocalRef(netscape_oji_ProxyClassLoaderFactory);
    }
    check_exceptions(env);
    return liveConnectProxy;
}

Here is the call graph for this function:

CSecureEnv* GetSecureJNI ( JNIEnv env,
jobject  thread 
)

Returns the secure JNI associated with the current thread (if any).

Definition at line 3128 of file CSecureEnv.cpp.

{
       CSecureEnv* secureJNI = NULL;
       
       jclass threadClass = env->GetObjectClass(thread);
       if (threadClass != NULL) {
              jfieldID fSecureEnvField = env->GetFieldID(threadClass, "fSecureEnv", "I");
              if (fSecureEnvField != NULL) {
                     secureJNI = (CSecureEnv*) env->GetIntField(thread, fSecureEnvField);
              } else {
                     env->ExceptionClear();
              }
              env->DeleteLocalRef(threadClass);
       }
       
       return secureJNI;
}
static void netscape_oji_JNIRunnable_run ( JNIEnv env,
jobject  self 
) [static]

Definition at line 174 of file CSecureEnv.cpp.

{
    JavaMessage* msg = (JavaMessage*) env->GetIntField(self, netscape_oji_JNIRunnable_mJavaMessageID);
    if (msg) {
        msg->execute(env);
        // what about upcalls?
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void netscape_oji_JNIThread_run ( JNIEnv env,
jobject  self 
) [static]

Native run method that communicates with LiveConnect from a Java thread.

Definition at line 117 of file CSecureEnv.cpp.

{
       CSecureEnv* secureEnv = NULL;
       jmethodID yieldMethod = NULL;
       jmethodID sleepMethod = NULL;
       
       jclass clazz = env->GetObjectClass(self);
       if (clazz != NULL) {
              // the field fSecureEnv contains a pointer to a CSecureEnv.
              jfieldID fSecureEnvField = env->GetFieldID(clazz, "fSecureEnv", "I");
              if (fSecureEnvField != NULL) {
                     secureEnv = (CSecureEnv*) env->GetIntField(self, fSecureEnvField);
              }
              yieldMethod = env->GetStaticMethodID(clazz, "yield", "()V");
              sleepMethod = env->GetStaticMethodID(clazz, "sleep", "(J)V");
       }
       
       // notify the secure JNI that we are here, and wait for messages to arrive.
       if (secureEnv != NULL) {
              jboolean isRunning = true;
              MRJSession* session = secureEnv->getSession();
              MRJMonitor requestMonitor(session, self);
              MRJMonitor replyMonitor(session);
              // NativeMonitor replyMonitor(secureEnv->getThreadManager());
              JavaMessageQueue requests(&requestMonitor), replies(&replyMonitor);
              secureEnv->initialize(env, &isRunning, &requests, &replies);
              
              // when this thread is running, no other thread can enter the request queue monitor.
              requests.enter();
              
              while (isRunning) {
                     // the protocol for now is dead simple:  get a message from the
                     // requests message queue, process it, and then put it back in
                     // the replies queue. This will get more elaborate to handle
                     // upcall requests. 
                     JavaMessage* msg = requests.getMessage();
                     if (msg != NULL) {
                            msg->execute(env);
                            secureEnv->savePendingException(env);
                            replies.putMessage(msg);
                            replies.notify();
                     } else {
                            // should we do sleep, timed wait, or what?
                            // env->CallStaticVoidMethod(clazz, yieldMethod);
                            // env->CallStaticVoidMethod(clazz, sleepMethod, jlong(kDefaultJMTime));
                            requests.wait();
                     }
              }
              
              requests.exit();
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

jobject ToGlobalRef ( JNIEnv env,
jobject  localRef 
) [inline]

Definition at line 56 of file CSecureEnv.cpp.

{
    jobject globalRef = env->NewGlobalRef(localRef);
    // env->DeleteLocalRef(localRef);   // not necessary from native methods. done en-masse.
    return globalRef;
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 170 of file CSecureEnv.cpp.

Definition at line 171 of file CSecureEnv.cpp.

Definition at line 172 of file CSecureEnv.cpp.