Back to index

lightning-sunbird  0.9+nobinonly
CSecureEnv.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is mozilla.org code.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Sun Microsystems, Inc.
00018  * Portions created by the Initial Developer are Copyright (C) 1998
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either of the GNU General Public License Version 2 or later (the "GPL"),
00025  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 /*
00038        CSecureEnv.cpp
00039 
00040        Rewritten for use with MRJ plugin by Patrick C. Beard. Just forwards all
00041        calls through the underlying JNIEnv that this wraps. Eventually, it will
00042        communicate with the underlying threads using a message queue.
00043  */    
00044 
00045 #include "CSecureEnv.h"
00046 #include "nsISecurityContext.h"
00047 
00048 #include "MRJPlugin.h"
00049 #include "MRJSession.h"
00050 #include "nsIThreadManager.h"
00051 #include "nsIJVMManager.h"
00052 
00053 #include "MRJMonitor.h"
00054 #include "NativeMonitor.h"
00055 #include "JavaMessageQueue.h"
00056 
00057 #if 0
00058 static NS_DEFINE_IID(kISecureEnvIID, NS_ISECUREENV_IID);
00059 static NS_DEFINE_IID(kIRunnableIID, NS_IRUNNABLE_IID);
00060 static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
00061 #endif
00062 
00063 JavaMessageQueue::JavaMessageQueue(Monitor* monitor)
00064        :      mFirst(NULL), mLast(NULL), mMonitor(monitor)
00065 {
00066 }
00067 
00068 void JavaMessageQueue::putMessage(JavaMessage* msg)
00069 {
00070        if (mFirst == NULL) {
00071               mFirst = mLast = msg;
00072        } else {
00073               mLast->setNext(msg);
00074               mLast = msg;
00075        }
00076        msg->setNext(NULL);
00077 }
00078 
00079 JavaMessage* JavaMessageQueue::getMessage()
00080 {
00081        JavaMessage* msg = mFirst;
00082        if (msg != NULL) {
00083               mFirst = mFirst->getNext();
00084               if (mFirst == NULL) mLast = NULL;
00085        }
00086        return msg;
00087 }
00088 
00089 void JavaMessageQueue::enter()
00090 {
00091        mMonitor->enter();
00092 }
00093 
00094 void JavaMessageQueue::exit()
00095 {
00096        mMonitor->exit();
00097 }
00098 
00099 void JavaMessageQueue::wait()
00100 {
00101        mMonitor->wait();
00102 }
00103 
00104 void JavaMessageQueue::wait(long long millis)
00105 {
00106        mMonitor->wait(millis);
00107 }
00108 
00109 void JavaMessageQueue::notify()
00110 {
00111        mMonitor->notify();
00112 }
00113 
00117 static void netscape_oji_JNIThread_run(JNIEnv* env, jobject self)
00118 {
00119        CSecureEnv* secureEnv = NULL;
00120        jmethodID yieldMethod = NULL;
00121        jmethodID sleepMethod = NULL;
00122        
00123        jclass clazz = env->GetObjectClass(self);
00124        if (clazz != NULL) {
00125               // the field fSecureEnv contains a pointer to a CSecureEnv.
00126               jfieldID fSecureEnvField = env->GetFieldID(clazz, "fSecureEnv", "I");
00127               if (fSecureEnvField != NULL) {
00128                      secureEnv = (CSecureEnv*) env->GetIntField(self, fSecureEnvField);
00129               }
00130               yieldMethod = env->GetStaticMethodID(clazz, "yield", "()V");
00131               sleepMethod = env->GetStaticMethodID(clazz, "sleep", "(J)V");
00132        }
00133        
00134        // notify the secure JNI that we are here, and wait for messages to arrive.
00135        if (secureEnv != NULL) {
00136               jboolean isRunning = true;
00137               MRJSession* session = secureEnv->getSession();
00138               MRJMonitor requestMonitor(session, self);
00139               MRJMonitor replyMonitor(session);
00140               // NativeMonitor replyMonitor(secureEnv->getThreadManager());
00141               JavaMessageQueue requests(&requestMonitor), replies(&replyMonitor);
00142               secureEnv->initialize(env, &isRunning, &requests, &replies);
00143               
00144               // when this thread is running, no other thread can enter the request queue monitor.
00145               requests.enter();
00146               
00147               while (isRunning) {
00148                      // the protocol for now is dead simple:  get a message from the
00149                      // requests message queue, process it, and then put it back in
00150                      // the replies queue. This will get more elaborate to handle
00151                      // upcall requests. 
00152                      JavaMessage* msg = requests.getMessage();
00153                      if (msg != NULL) {
00154                             msg->execute(env);
00155                             replies.putMessage(msg);
00156                             replies.notify();
00157                      } else {
00158                             // should we do sleep, timed wait, or what?
00159                             // env->CallStaticVoidMethod(clazz, yieldMethod);
00160                             // env->CallStaticVoidMethod(clazz, sleepMethod, jlong(kDefaultJMTime));
00161                             requests.wait();
00162                      }
00163               }
00164               
00165               requests.exit();
00166        }
00167 }
00168 
00173 static void CreateJNIThread(CSecureEnv* secureEnv)
00174 {
00175        nsIThreadManager* manager = secureEnv->getThreadManager();
00176        MRJSession* session = secureEnv->getSession();
00177        JNIEnv* env = session->getCurrentEnv();
00178        jclass JNIThreadClass = env->FindClass("netscape/oji/JNIThread");
00179        if (JNIThreadClass != NULL) {
00180               JNINativeMethod method = { "run", "()V", &netscape_oji_JNIThread_run };
00181               env->RegisterNatives(JNIThreadClass, &method, 1);
00182               jmethodID constructorID = env->GetMethodID(JNIThreadClass, "<init>", "(I)V");
00183               if (constructorID != NULL) {
00184                      jobject javaThread = env->NewObject(JNIThreadClass, constructorID, secureEnv);
00185                      for (;;) {
00186                             // give time to Java, to allow the thread to come up.
00187                             session->idle(kDefaultJMTime);
00188                             // has the thread made contact?
00189                             if (secureEnv->isInitialized())
00190                                    break;
00191                             // give time to NSPR, to avoid hanging too long.
00192                             manager->Sleep();
00193                      }
00194               }
00195        }
00196 }
00197 
00201 class CreateNativeThreadMessage : public NativeMessage {
00202        nsresult* mResult;
00203        PRUint32* mThreadID;
00204        CSecureEnv* mSecureEnv;
00205 public:
00206        CreateNativeThreadMessage(nsresult* outResult, PRUint32* outThreadID, CSecureEnv* secureEnv)
00207               :      mResult(outResult), mThreadID(outThreadID), mSecureEnv(secureEnv)
00208        {
00209        }
00210 
00211        virtual void execute()
00212        {
00213               nsIThreadManager* manager = mSecureEnv->getThreadManager();
00214               *mResult = manager->CreateThread(mThreadID, mSecureEnv);
00215        }
00216 };
00217 
00221 static void CreateNativeThread(CSecureEnv* secureEnv)
00222 {
00223        nsresult result;
00224        PRUint32 threadID;
00225        MRJSession* session = secureEnv->getSession();
00226        
00227        // cause a native thread to be created on our behalf. Perhaps this should be a message we send to the
00228        // session itself. otherwise we could have reentrancy problems.
00229        CreateNativeThreadMessage message(&result, &threadID, secureEnv);
00230        session->sendMessage(&message);
00231 
00232        if (session->onMainThread()) {
00233               // give time to other native threads, so the new thread can come up.
00234               nsIThreadManager* manager = secureEnv->getThreadManager();
00235               while (!secureEnv->isInitialized()) {
00236                      manager->Sleep();
00237               }
00238        } else {
00239               // sleep the current Java thread until we rendezvous with the Native thread.
00240               JNIEnv* env = session->getCurrentEnv();
00241               jclass threadClass = env->FindClass("java/lang/Thread");
00242               if (threadClass != NULL) {
00243                      jmethodID sleepMethod = env->GetStaticMethodID(threadClass, "sleep", "(J)V");
00244                      if (sleepMethod != NULL) {
00245                             while (!secureEnv->isInitialized())
00246                                    env->CallStaticVoidMethod(threadClass, sleepMethod, jlong(kDefaultJMTime));
00247                      }
00248                      env->DeleteLocalRef(threadClass);
00249               }
00250        }
00251 }
00252 
00256 NS_IMETHODIMP CSecureEnv::Run()
00257 {
00258        jboolean isRunning = true;
00259        NativeMonitor requestMonitor(mSession, mThreadManager);
00260        MRJMonitor replyMonitor(mSession);
00261        JavaMessageQueue requests(&requestMonitor), replies(&replyMonitor);
00262        // initialize(env, self, &isRunning, &requests, &replies);
00263        
00264        // we have to create the Proxy JNI here, so it associated with this thread.
00265        nsIJVMManager* manager = mPlugin->getManager();
00266        manager->CreateProxyJNI(this, &mProxyEnv);
00267        
00268        mIsRunning = &isRunning;
00269        mNativeQueue = &requests;
00270        mJavaQueue = &replies;
00271        
00272        // when this thread is running, no other thread can enter the request queue monitor.
00273        requests.enter();
00274        
00275        while (isRunning) {
00276               // the protocol for now is dead simple:  get a message from the
00277               // requests message queue, process it, and then put it back in
00278               // the replies queue. This will get more elaborate to handle
00279               // upcall requests. 
00280               JavaMessage* msg = requests.getMessage();
00281               if (msg != NULL) {
00282                      msg->execute(mProxyEnv);
00283                      replies.putMessage(msg);
00284                      replies.notify();
00285               } else {
00286                      // should we do sleep, timed wait, or what?
00287                      // env->CallStaticVoidMethod(clazz, yieldMethod);
00288                      // env->CallStaticVoidMethod(clazz, sleepMethod, jlong(kDefaultJMTime));
00289                      requests.wait();
00290               }
00291        }
00292        
00293        requests.exit();
00294 
00295        return NS_OK;
00296 }
00297 
00301 void CSecureEnv::sendMessageToJava(JavaMessage* msg)
00302 {
00303        messageLoop(mProxyEnv, msg, mJavaQueue, mNativeQueue, true);
00304 }
00305 
00309 void CSecureEnv::sendMessageFromJava(JNIEnv* javaEnv, JavaMessage* msg, Boolean busyWaiting)
00310 {
00311        messageLoop(javaEnv, msg, mNativeQueue, mJavaQueue, busyWaiting);
00312 }
00313 
00315 // from nsISupports and AggregatedQueryInterface:
00316 
00317 // Thes macro expands to the aggregated query interface scheme.
00318 
00319 #if 0
00320 NS_IMPL_AGGREGATED(CSecureEnv)
00321 
00322 NS_METHOD
00323 CSecureEnv::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
00324 {
00325     if (aIID.Equals(kISupportsIID)) {
00326       *aInstancePtr = GetInner();
00327       AddRef();
00328       return NS_OK;
00329     }
00330     if (aIID.Equals(kISecureEnvIID)) {
00331         *aInstancePtr = (nsISecureEnv*) this;
00332         AddRef();
00333         return NS_OK;
00334     }
00335     if (aIID.Equals(kIRunnableIID)) {
00336         *aInstancePtr = (nsIRunnable*) this;
00337         AddRef();
00338         return NS_OK;
00339     }
00340     return NS_NOINTERFACE;
00341 }
00342 #endif
00343 
00344 const InterfaceInfo CSecureEnv::sInterfaces[] = {
00345        { NS_ISECUREENV_IID, INTERFACE_OFFSET(CSecureEnv, nsISecureEnv) },
00346        { NS_IRUNNABLE_IID, INTERFACE_OFFSET(CSecureEnv, nsIRunnable) },
00347 };
00348 const UInt32 CSecureEnv::kInterfaceCount = sizeof(sInterfaces) / sizeof(InterfaceInfo);
00349 
00351 // CSecureEnv::CSecureEnv
00353 // Implements the CSecureJNI object for creating object, invoking method, 
00354 // getting/setting field in JNI with security context.
00355 //
00356 // parameters :
00357 //
00358 // return :
00359 // 
00360 // notes :
00361 //
00362 CSecureEnv::CSecureEnv(MRJPlugin* plugin, JNIEnv* proxyEnv, JNIEnv* javaEnv)
00363        :      SupportsMixin(this, sInterfaces, kInterfaceCount),
00364               mPlugin(plugin), mProxyEnv(proxyEnv), mJavaEnv(javaEnv),
00365               mSession(plugin->getSession()), mThreadManager(plugin->getThreadManager()),
00366               mIsRunning(NULL), mJavaQueue(NULL), mNativeQueue(NULL)
00367 {
00368        // need to create the JNIThread for communicating with Java.
00369        if (mJavaEnv != NULL)
00370               CreateNativeThread(this);
00371        else
00372            CreateJNIThread(this);
00373 }
00374 
00375 
00377 // CSecureEnv::~CSecureEnv
00379 // Implements the CSecureEnv object for creating object, invoking method, 
00380 // getting/setting field in JNI with security context.
00381 //
00382 // parameters :
00383 //
00384 // return :
00385 // 
00386 // notes :
00387 //
00388 CSecureEnv::~CSecureEnv()  
00389 {
00390        // Tell the Java thread to die.
00391        if (mIsRunning != NULL) {
00392               *mIsRunning = false;
00393               mJavaQueue->notify();
00394        }
00395 }
00396 
00397 void CSecureEnv::initialize(JNIEnv* javaEnv, jboolean* isRunning, JavaMessageQueue* javaQueue, JavaMessageQueue* nativeQueue)
00398 {
00399        mJavaEnv = javaEnv;
00400        mIsRunning = isRunning;
00401        mJavaQueue = javaQueue;
00402        mNativeQueue = nativeQueue;
00403 }
00404 
00406 // CSecureEnv::Create
00408 // Create the CSecureEnv object for creating object, invoking method, 
00409 // getting/setting field in JNI with security context.
00410 //
00411 // parameters :
00412 //
00413 // return :
00414 // 
00415 // notes :
00416 //
00417 NS_METHOD
00418 CSecureEnv::Create(MRJPlugin* plugin, JNIEnv* proxyEnv, const nsIID& aIID, void* *aInstancePtr)
00419 {
00420        CSecureEnv* secureEnv = new CSecureEnv(plugin, proxyEnv);
00421        if (secureEnv == NULL)
00422            return NS_ERROR_OUT_OF_MEMORY;
00423        nsresult result = secureEnv->QueryInterface(aIID, aInstancePtr);
00424        if (result != NS_OK) {
00425               delete secureEnv;
00426               return result;
00427        }
00428        return NS_OK;
00429 }
00430 
00432 // from nsISecureJNI:
00433 //
00434 
00435 
00437 // CSecureEnv::NewObject
00439 // Create new Java object in LiveConnect.
00440 //
00441 // @param env        -- JNIEnv pointer.
00442 // @param clazz      -- Java Class object.
00443 // @param methodID   -- Method id
00444 // @param args       -- arguments for invoking the constructor.
00445 // @param result     -- return new Java object.
00446 // @param ctx        -- security context 
00447 //
00448 
00449 class NewObjectMessage : public JavaMessage {
00450        jclass clazz;
00451        jmethodID methodID;
00452        jvalue* args;
00453        jobject* result;
00454 
00455 public:
00456        NewObjectMessage(jclass clazz,  jmethodID methodID, jvalue *args, jobject* result)
00457        {
00458               this->clazz = clazz;
00459               this->methodID = methodID;
00460               this->args = args;
00461               this->result = result;
00462        }
00463        
00464        virtual void execute(JNIEnv* env)
00465        {
00466               *result = env->NewObjectA(clazz, methodID, args);
00467        }
00468 };
00469 
00470 NS_IMETHODIMP CSecureEnv::NewObject(/*[in]*/  jclass clazz, 
00471                                      /*[in]*/  jmethodID methodID, 
00472                                      /*[in]*/  jvalue *args, 
00473                                      /*[out]*/ jobject* result,
00474                                      /*[in]*/  nsISecurityContext* ctx)
00475 {
00476     if (clazz == NULL || methodID == NULL)
00477         return NS_ERROR_NULL_POINTER;
00478 
00479     // Call method on Java side
00480     NewObjectMessage msg(clazz, methodID, args, result);
00481     sendMessageToJava(&msg);
00482        // *result = m_env->NewObjectA(clazz, methodID, args);
00483        
00484        return NS_OK;
00485 }
00486 
00487 
00489 // CSecureEnv::CallMethod
00491 // Invoke method on Java object in LiveConnect.
00492 //
00493 // @param type       -- Return type
00494 // @param obj        -- Java object.
00495 // @param methodID   -- Method id
00496 // @param result     -- return result of invocation.
00497 // @param ctx        -- security context 
00498 //
00499 
00500 class CallMethodMessage : public JavaMessage {
00501        jni_type type;
00502        jobject obj;
00503        jmethodID methodID;
00504        jvalue* args;
00505        jvalue* result;
00506 
00507 public:
00508        CallMethodMessage(jni_type type, jobject obj, jmethodID methodID, jvalue *args, jvalue* result)
00509        {
00510               this->type = type;
00511               this->obj = obj;
00512               this->methodID = methodID;
00513               this->args = args;
00514               this->result = result;
00515        }
00516        
00517        virtual void execute(JNIEnv* env)
00518        {
00519               switch (type) {
00520               case jobject_type:
00521                      result->l = env->CallObjectMethodA(obj, methodID, args);
00522                      break;
00523               case jboolean_type:
00524                      result->z = env->CallBooleanMethodA(obj, methodID, args);
00525                      break;
00526               case jbyte_type:
00527                      result->b = env->CallByteMethodA(obj, methodID, args);
00528                      break;
00529               case jchar_type:
00530                      result->c = env->CallCharMethodA(obj, methodID, args);
00531                      break;
00532               case jshort_type:
00533                      result->s = env->CallShortMethodA(obj, methodID, args);
00534                      break;
00535               case jint_type:
00536                      result->i = env->CallIntMethodA(obj, methodID, args);
00537                      break;
00538               case jlong_type:
00539                      result->j = env->CallLongMethodA(obj, methodID, args);
00540                      break;
00541               case jfloat_type:
00542                      result->f = env->CallFloatMethodA(obj, methodID, args);
00543                      break;
00544               case jdouble_type:
00545                      result->d = env->CallDoubleMethodA(obj, methodID, args);
00546                      break;
00547               case jvoid_type:
00548                      env->CallVoidMethodA(obj, methodID, args);
00549                      break;
00550               }
00551        }
00552 };
00553 
00554 NS_IMETHODIMP CSecureEnv::CallMethod(/*[in]*/  jni_type type,
00555                                       /*[in]*/  jobject obj, 
00556                                       /*[in]*/  jmethodID methodID, 
00557                                       /*[in]*/  jvalue *args, 
00558                                       /*[out]*/ jvalue* result,
00559                                       /*[in]*/  nsISecurityContext* ctx)
00560 {
00561     if (obj == NULL || methodID == NULL)
00562         return NS_ERROR_NULL_POINTER;
00563 
00564        // Call method on Java side
00565        // return CallJavaMethod(obj, method, args, ctx, result);
00566        CallMethodMessage msg(type, obj, methodID, args, result);
00567        sendMessageToJava(&msg);
00568        
00569        return NS_OK;
00570 }
00571 
00572 
00574 // CSecureEnv::CallNonvirtualMethod
00576 // Invoke non-virtual method on Java object in LiveConnect.
00577 //
00578 // @param obj        -- Java object.
00579 // @param methodID   -- Method id
00580 // @param args       -- arguments for invoking the constructor.
00581 // @param result     -- return result of invocation.
00582 // @param ctx        -- security context 
00583 //
00584 
00585 class CallNonvirtualMethodMessage : public JavaMessage {
00586        jni_type type;
00587        jobject obj;
00588        jclass clazz;
00589        jmethodID methodID;
00590        jvalue* args;
00591        jvalue* result;
00592 
00593 public:
00594        CallNonvirtualMethodMessage(jni_type type, jobject obj, jclass clazz, jmethodID methodID, jvalue *args, jvalue* result)
00595        {
00596               this->type = type;
00597               this->obj = obj;
00598               this->clazz = clazz;
00599               this->methodID = methodID;
00600               this->args = args;
00601               this->result = result;
00602        }
00603        
00604        virtual void execute(JNIEnv* env)
00605        {
00606               switch (type) {
00607               case jobject_type:
00608                      result->l = env->CallNonvirtualObjectMethodA(obj, clazz, methodID, args);
00609                      break;
00610               case jboolean_type:
00611                      result->z = env->CallNonvirtualBooleanMethodA(obj, clazz, methodID, args);
00612                      break;
00613               case jbyte_type:
00614                      result->b = env->CallNonvirtualByteMethodA(obj, clazz, methodID, args);
00615                      break;
00616               case jchar_type:
00617                      result->c = env->CallNonvirtualCharMethodA(obj, clazz, methodID, args);
00618                      break;
00619               case jshort_type:
00620                      result->s = env->CallNonvirtualShortMethodA(obj, clazz, methodID, args);
00621                      break;
00622               case jint_type:
00623                      result->i = env->CallNonvirtualIntMethodA(obj, clazz, methodID, args);
00624                      break;
00625               case jlong_type:
00626                      result->j = env->CallNonvirtualLongMethodA(obj, clazz, methodID, args);
00627                      break;
00628               case jfloat_type:
00629                      result->f = env->CallNonvirtualFloatMethodA(obj, clazz, methodID, args);
00630                      break;
00631               case jdouble_type:
00632                      result->d = env->CallNonvirtualDoubleMethodA(obj, clazz, methodID, args);
00633                      break;
00634               case jvoid_type:
00635                      env->CallNonvirtualVoidMethodA(obj, clazz, methodID, args);
00636                      break;
00637               }
00638        }
00639 };
00640 
00641 NS_IMETHODIMP CSecureEnv::CallNonvirtualMethod(/*[in]*/  jni_type type,
00642                                                 /*[in]*/  jobject obj, 
00643                                                 /*[in]*/  jclass clazz,
00644                                                 /*[in]*/  jmethodID methodID,
00645                                                 /*[in]*/  jvalue *args, 
00646                                                 /*[out]*/ jvalue* result,
00647                                                 /*[in]*/  nsISecurityContext* ctx)
00648 {
00649     if (obj == NULL || clazz == NULL || methodID == NULL)
00650         return NS_ERROR_NULL_POINTER;
00651 
00652        // Call non-virtual method on Java side
00653        // return CallJavaMethod(obj, method, args, ctx, result);
00654        CallNonvirtualMethodMessage msg(type, obj, clazz, methodID, args, result);
00655        sendMessageToJava(&msg);
00656        
00657        return NS_OK;
00658 }
00659 
00660 
00662 // CSecureEnv::GetField
00664 // Get a field on Java object in LiveConnect.
00665 //
00666 // @param obj        -- Java object.
00667 // @param fieldID    -- field id
00668 // @param result     -- return field value
00669 // @param ctx        -- security context 
00670 //
00671 
00672 class GetFieldMessage : public JavaMessage {
00673        jni_type type;
00674        jobject obj;
00675        jfieldID fieldID;
00676        jvalue* args;
00677        jvalue* result;
00678 
00679 public:
00680        GetFieldMessage(jni_type type, jobject obj, jfieldID fieldID, jvalue *args, jvalue* result)
00681        {
00682               this->type = type;
00683               this->obj = obj;
00684               this->fieldID = fieldID;
00685               this->args = args;
00686               this->result = result;
00687        }
00688        
00689        virtual void execute(JNIEnv* env)
00690        {
00691               switch (type) {
00692               case jobject_type:
00693                      result->l = env->GetObjectField(obj, fieldID);
00694                      break;
00695               case jboolean_type:
00696                      result->z = env->GetBooleanField(obj, fieldID);
00697                      break;
00698               case jbyte_type:
00699                      result->b = env->GetByteField(obj, fieldID);
00700                      break;
00701               case jchar_type:
00702                      result->c = env->GetCharField(obj, fieldID);
00703                      break;
00704               case jshort_type:
00705                      result->s = env->GetShortField(obj, fieldID);
00706                      break;
00707               case jint_type:
00708                      result->i = env->GetIntField(obj, fieldID);
00709                      break;
00710               case jlong_type:
00711                      result->j = env->GetLongField(obj, fieldID);
00712                      break;
00713               case jfloat_type:
00714                      result->f = env->GetFloatField(obj, fieldID);
00715                      break;
00716               case jdouble_type:
00717                      result->d = env->GetDoubleField(obj, fieldID);
00718                      break;
00719               }
00720        }
00721 };
00722 
00723 NS_IMETHODIMP CSecureEnv::GetField(/*[in]*/  jni_type type,
00724                                     /*[in]*/  jobject obj, 
00725                                     /*[in]*/  jfieldID fieldID,
00726                                     /*[out]*/ jvalue* result,
00727                                     /*[in]*/  nsISecurityContext* ctx)
00728 {
00729     if (mJavaEnv == NULL || obj == NULL || fieldID == NULL)
00730         return NS_ERROR_NULL_POINTER;
00731 
00732     // Get field on Java side
00733     // return GetJavaField(obj, field, ctx, result);
00734     
00735        JNIEnv* env = mJavaEnv;
00736        switch (type) {
00737        case jobject_type:
00738               result->l = env->GetObjectField(obj, fieldID);
00739               break;
00740        case jboolean_type:
00741               result->z = env->GetBooleanField(obj, fieldID);
00742               break;
00743        case jbyte_type:
00744               result->b = env->GetByteField(obj, fieldID);
00745               break;
00746        case jchar_type:
00747               result->c = env->GetCharField(obj, fieldID);
00748               break;
00749        case jshort_type:
00750               result->s = env->GetShortField(obj, fieldID);
00751               break;
00752        case jint_type:
00753               result->i = env->GetIntField(obj, fieldID);
00754               break;
00755        case jlong_type:
00756               result->j = env->GetLongField(obj, fieldID);
00757               break;
00758        case jfloat_type:
00759               result->f = env->GetFloatField(obj, fieldID);
00760               break;
00761        case jdouble_type:
00762               result->d = env->GetDoubleField(obj, fieldID);
00763               break;
00764        }
00765        
00766        return NS_OK;
00767 }
00768 
00769 
00771 // CSecureEnv::SetField
00773 //
00774 // Set a field on Java object in LiveConnect.
00775 //
00776 // @param obj        -- Java object.
00777 // @param fieldID    -- field id
00778 // @param result     -- field value to set
00779 // @param ctx        -- security context 
00780 //
00781 NS_IMETHODIMP CSecureEnv::SetField(/*[in]*/ jni_type type,
00782                                     /*[in]*/ jobject obj, 
00783                                     /*[in]*/ jfieldID fieldID,
00784                                     /*[in]*/ jvalue val,
00785                                     /*[in]*/ nsISecurityContext* ctx)
00786 {
00787     if (mJavaEnv == NULL || obj == NULL || fieldID == NULL)
00788         return NS_ERROR_NULL_POINTER;
00789 
00790     // Set field on Java side
00791     // return SetJavaField(obj, field, val, ctx);
00792 
00793        JNIEnv* env = mJavaEnv;
00794        switch (type) {
00795        case jobject_type:
00796               env->SetObjectField(obj, fieldID, val.l);
00797               break;
00798        case jboolean_type:
00799               env->SetBooleanField(obj, fieldID, val.z);
00800               break;
00801        case jbyte_type:
00802               env->SetByteField(obj, fieldID, val.b);
00803               break;
00804        case jchar_type:
00805               env->SetCharField(obj, fieldID, val.c);
00806               break;
00807        case jshort_type:
00808               env->SetShortField(obj, fieldID, val.s);
00809               break;
00810        case jint_type:
00811               env->SetIntField(obj, fieldID, val.i);
00812               break;
00813        case jlong_type:
00814               env->SetLongField(obj, fieldID, val.j);
00815               break;
00816        case jfloat_type:
00817               env->SetFloatField(obj, fieldID, val.f);
00818               break;
00819        case jdouble_type:
00820               env->SetDoubleField(obj, fieldID, val.d);
00821               break;
00822        }
00823        
00824        return NS_OK;
00825 }
00826 
00827 
00829 // CSecureEnv::CallStaticMethod
00831 //
00832 // Invoke static method on Java object in LiveConnect.
00833 //
00834 // @param obj        -- Java object.
00835 // @param methodID   -- method id
00836 // @param args       -- arguments for invoking the constructor.
00837 // @param result     -- return result of invocation.
00838 // @param ctx        -- security context 
00839 //
00840 
00841 class CallStaticMethodMessage : public JavaMessage {
00842        jni_type type;
00843        jclass clazz;
00844        jmethodID methodID;
00845        jvalue* args;
00846        jvalue* result;
00847 
00848 public:
00849        CallStaticMethodMessage(jni_type type, jclass clazz, jmethodID methodID, jvalue *args, jvalue* result)
00850        {
00851               this->type = type;
00852               this->clazz = clazz;
00853               this->methodID = methodID;
00854               this->args = args;
00855               this->result = result;
00856        }
00857        
00858        virtual void execute(JNIEnv* env)
00859        {
00860               switch (type) {
00861               case jobject_type:
00862                      result->l = env->CallStaticObjectMethodA(clazz, methodID, args);
00863                      break;
00864               case jboolean_type:
00865                      result->z = env->CallStaticBooleanMethodA(clazz, methodID, args);
00866                      break;
00867               case jbyte_type:
00868                      result->b = env->CallStaticByteMethodA(clazz, methodID, args);
00869                      break;
00870               case jchar_type:
00871                      result->c = env->CallStaticCharMethodA(clazz, methodID, args);
00872                      break;
00873               case jshort_type:
00874                      result->s = env->CallStaticShortMethodA(clazz, methodID, args);
00875                      break;
00876               case jint_type:
00877                      result->i = env->CallStaticIntMethodA(clazz, methodID, args);
00878                      break;
00879               case jlong_type:
00880                      result->j = env->CallStaticLongMethodA(clazz, methodID, args);
00881                      break;
00882               case jfloat_type:
00883                      result->f = env->CallStaticFloatMethodA(clazz, methodID, args);
00884                      break;
00885               case jdouble_type:
00886                      result->d = env->CallStaticDoubleMethodA(clazz, methodID, args);
00887                      break;
00888               case jvoid_type:
00889                      env->CallStaticVoidMethodA(clazz, methodID, args);
00890                      break;
00891               }
00892        }
00893 };
00894 
00895 NS_IMETHODIMP CSecureEnv::CallStaticMethod(/*[in]*/  jni_type type,
00896                                             /*[in]*/  jclass clazz,
00897                                             /*[in]*/  jmethodID methodID,
00898                                             /*[in]*/  jvalue *args, 
00899                                             /*[out]*/ jvalue* result,
00900                                             /*[in]*/  nsISecurityContext* ctx)
00901 {
00902     if (clazz == NULL || methodID == NULL)
00903         return NS_ERROR_NULL_POINTER;
00904 
00905        // Call method on Java side
00906        // return CallJavaMethod(NULL, method, args, ctx, result);
00907        CallStaticMethodMessage msg(type, clazz, methodID, args, result);
00908        sendMessageToJava(&msg);
00909 
00910        return NS_OK;
00911 }
00912 
00913 
00915 // CSecureEnv::GetStaticField
00917 // Get a static field on Java object in LiveConnect.
00918 //
00919 // @param obj        -- Java object.
00920 // @param fieldID    -- field id
00921 // @param result     -- return field value
00922 // @param ctx        -- security context 
00923 //
00924 
00925 
00926 class GetStaticFieldMessage : public JavaMessage {
00927        jni_type type;
00928        jclass clazz;
00929        jfieldID fieldID;
00930        jvalue* args;
00931        jvalue* result;
00932 
00933 public:
00934        GetStaticFieldMessage(jni_type type, jclass clazz, jfieldID fieldID, jvalue* result)
00935        {
00936               this->type = type;
00937               this->clazz = clazz;
00938               this->fieldID = fieldID;
00939               this->args = args;
00940               this->result = result;
00941        }
00942        
00943        virtual void execute(JNIEnv* env)
00944        {
00945               switch (type) {
00946               case jobject_type:
00947                      result->l = env->GetStaticObjectField(clazz, fieldID);
00948                      break;
00949               case jboolean_type:
00950                      result->z = env->GetStaticBooleanField(clazz, fieldID);
00951                      break;
00952               case jbyte_type:
00953                      result->b = env->GetStaticByteField(clazz, fieldID);
00954                      break;
00955               case jchar_type:
00956                      result->c = env->GetStaticCharField(clazz, fieldID);
00957                      break;
00958               case jshort_type:
00959                      result->s = env->GetStaticShortField(clazz, fieldID);
00960                      break;
00961               case jint_type:
00962                      result->i = env->GetStaticIntField(clazz, fieldID);
00963                      break;
00964               case jlong_type:
00965                      result->j = env->GetStaticLongField(clazz, fieldID);
00966                      break;
00967               case jfloat_type:
00968                      result->f = env->GetStaticFloatField(clazz, fieldID);
00969                      break;
00970               case jdouble_type:
00971                      result->d = env->GetStaticDoubleField(clazz, fieldID);
00972                      break;
00973               }
00974        }
00975 };
00976 
00977 NS_IMETHODIMP CSecureEnv::GetStaticField(/*[in]*/  jni_type type,
00978                                           /*[in]*/  jclass clazz, 
00979                                           /*[in]*/  jfieldID fieldID,
00980                                           /*[out]*/ jvalue* result,
00981                                           /*[in]*/  nsISecurityContext* ctx)
00982 {
00983     if (mJavaEnv == NULL || clazz == NULL || fieldID == NULL)
00984         return NS_ERROR_NULL_POINTER;
00985 
00986     // Get static field on Java side
00987        // return GetJavaField(NULL, field, ctx, result);
00988        // GetStaticFieldMessage msg(type, clazz, fieldID, result);
00989        // sendMessageToJava(&msg);
00990 
00991        // should be able to perform in Java env.
00992        JNIEnv* env = mJavaEnv;
00993        switch (type) {
00994        case jobject_type:
00995               result->l = env->GetStaticObjectField(clazz, fieldID);
00996               break;
00997        case jboolean_type:
00998               result->z = env->GetStaticBooleanField(clazz, fieldID);
00999               break;
01000        case jbyte_type:
01001               result->b = env->GetStaticByteField(clazz, fieldID);
01002               break;
01003        case jchar_type:
01004               result->c = env->GetStaticCharField(clazz, fieldID);
01005               break;
01006        case jshort_type:
01007               result->s = env->GetStaticShortField(clazz, fieldID);
01008               break;
01009        case jint_type:
01010               result->i = env->GetStaticIntField(clazz, fieldID);
01011               break;
01012        case jlong_type:
01013               result->j = env->GetStaticLongField(clazz, fieldID);
01014               break;
01015        case jfloat_type:
01016               result->f = env->GetStaticFloatField(clazz, fieldID);
01017               break;
01018        case jdouble_type:
01019               result->d = env->GetStaticDoubleField(clazz, fieldID);
01020               break;
01021        }
01022        
01023        return NS_OK;
01024 }
01025 
01026 
01028 // CSecureEnv::SetStaticField
01030 // Set a static field on Java object in LiveConnect.
01031 //
01032 // @param obj        -- Java object.
01033 // @param fieldID    -- field id
01034 // @param result     -- field value to set
01035 // @param ctx        -- security context 
01036 //
01037 NS_IMETHODIMP CSecureEnv::SetStaticField(/*[in]*/  jni_type type,
01038                                           /*[in]*/ jclass clazz, 
01039                                           /*[in]*/ jfieldID fieldID,
01040                                           /*[in]*/ jvalue val,
01041                                           /*[in]*/ nsISecurityContext* ctx)
01042 {
01043     if (mJavaEnv == NULL || clazz == NULL || fieldID == NULL)
01044         return NS_ERROR_NULL_POINTER;
01045 
01046        // Set static field on Java side
01047        // return SetJavaField(NULL, field, val, ctx);
01048 
01049        JNIEnv* env = mJavaEnv;
01050        switch (type) {
01051        case jobject_type:
01052               env->SetStaticObjectField(clazz, fieldID, val.l);
01053               break;
01054        case jboolean_type:
01055               env->SetStaticBooleanField(clazz, fieldID, val.z);
01056               break;
01057        case jbyte_type:
01058               env->SetStaticByteField(clazz, fieldID, val.b);
01059               break;
01060        case jchar_type:
01061               env->SetStaticCharField(clazz, fieldID, val.c);
01062               break;
01063        case jshort_type:
01064               env->SetStaticShortField(clazz, fieldID, val.s);
01065               break;
01066        case jint_type:
01067               env->SetStaticIntField(clazz, fieldID, val.i);
01068               break;
01069        case jlong_type:
01070               env->SetStaticLongField(clazz, fieldID, val.j);
01071               break;
01072        case jfloat_type:
01073               env->SetStaticFloatField(clazz, fieldID, val.f);
01074               break;
01075        case jdouble_type:
01076               env->SetStaticDoubleField(clazz, fieldID, val.d);
01077               break;
01078        }
01079        
01080        return NS_OK;
01081 }
01082 
01083 
01084 NS_IMETHODIMP CSecureEnv::GetVersion(/*[out]*/ jint* version) 
01085 {
01086     if (version == NULL)
01087         return NS_ERROR_NULL_POINTER;
01088     
01089        JNIEnv* env = mSession->getCurrentEnv();
01090        *version = env->GetVersion();
01091 
01092     return NS_OK;
01093 }
01094 
01098 class DefineClassMessage : public JavaMessage {
01099        const char* name;
01100        jobject loader;
01101        const jbyte *buf;
01102        jsize len;
01103        jclass* clazz;
01104 public:
01105        DefineClassMessage(const char* name, jobject loader, const jbyte *buf, jsize len, jclass* clazz)
01106        {
01107               this->name = name;
01108               this->loader = loader;
01109               this->buf = buf;
01110               this->len = len;
01111               this->clazz = clazz;
01112        }
01113        
01114        virtual void execute(JNIEnv* env)
01115        {
01116        *clazz = env->DefineClass(name, loader, buf, len);
01117        }
01118 };
01119 
01120 NS_IMETHODIMP CSecureEnv::DefineClass(/*[in]*/  const char* name,
01121                                        /*[in]*/  jobject loader,
01122                                        /*[in]*/  const jbyte *buf,
01123                                        /*[in]*/  jsize len,
01124                                        /*[out]*/ jclass* clazz) 
01125 {
01126     if (clazz == NULL)
01127         return NS_ERROR_NULL_POINTER;
01128     
01129     DefineClassMessage msg(name, loader, buf, len, clazz);
01130     sendMessageToJava(&msg);
01131 
01132     return NS_OK;
01133 }
01134 
01138 class FindClassMessage : public JavaMessage {
01139        const char* name;
01140        jclass* result;
01141 public:
01142        FindClassMessage(const char* name, jclass* result)
01143        {
01144               this->name = name;
01145               this->result = result;
01146        }
01147 
01148        virtual void execute(JNIEnv* env)
01149        {
01150               *result = env->FindClass(name);
01151        }
01152 };
01153 
01154 NS_IMETHODIMP CSecureEnv::FindClass(/*[in]*/  const char* name, 
01155                                      /*[out]*/ jclass* clazz) 
01156 {
01157     if (clazz == NULL)
01158         return NS_ERROR_NULL_POINTER;
01159     
01160        // JNIEnv* env = mSession->getCurrentEnv();
01161        // *clazz = env->FindClass(name);
01162        FindClassMessage msg(name, clazz);
01163        sendMessageToJava(&msg);
01164 
01165     return NS_OK;
01166 }
01167 
01171 class GetSuperclassMessage : public JavaMessage {
01172        jclass sub;
01173        jclass* super;
01174 public:
01175        GetSuperclassMessage(jclass sub, jclass* super)
01176        {
01177               this->sub = sub;
01178               this->super = super;
01179        }
01180 
01181        virtual void execute(JNIEnv* env)
01182        {
01183        *super = env->GetSuperclass(sub);
01184        }
01185 };
01186 
01187 NS_IMETHODIMP CSecureEnv::GetSuperclass(/*[in]*/  jclass sub,
01188                                          /*[out]*/ jclass* super) 
01189 {
01190     if (mJavaEnv == NULL || super == NULL)
01191         return NS_ERROR_NULL_POINTER;
01192     
01193        // GetSuperclassMessage msg(sub, super);
01194        // sendMessageToJava(&msg);
01195        *super = mJavaEnv->GetSuperclass(sub);
01196 
01197     return NS_OK;
01198 }
01199 
01200 
01201 NS_IMETHODIMP CSecureEnv::IsAssignableFrom(/*[in]*/  jclass sub,
01202                                             /*[in]*/  jclass super,
01203                                             /*[out]*/ jboolean* result) 
01204 {
01205     if (mJavaEnv == NULL || result == NULL)
01206         return NS_ERROR_NULL_POINTER;
01207     
01208        // JNIEnv* env = mSession->getCurrentEnv();
01209        // *result = env->IsAssignableFrom(sub, super);
01210        *result = mJavaEnv->IsAssignableFrom(sub, super);
01211 
01212     return NS_OK;
01213 }
01214 
01215 
01216 NS_IMETHODIMP CSecureEnv::Throw(/*[in]*/  jthrowable obj,
01217                                  /*[out]*/ jint* result) 
01218 {
01219        if (mJavaEnv == NULL || result == NULL)
01220         return NS_ERROR_NULL_POINTER;
01221     
01222        // Huh? This doesn't really make sense.
01223     
01224     *result = mJavaEnv->Throw(obj);
01225 
01226     return NS_OK;
01227 }
01228 
01229 NS_IMETHODIMP CSecureEnv::ThrowNew(/*[in]*/  jclass clazz,
01230                                     /*[in]*/  const char *msg,
01231                                     /*[out]*/ jint* result) 
01232 {
01233     if (mJavaEnv == NULL || result == NULL)
01234         return NS_ERROR_NULL_POINTER;
01235     
01236     *result = mJavaEnv->ThrowNew(clazz, msg);
01237 
01238     return NS_OK;
01239 }
01240 
01241 
01242 NS_IMETHODIMP CSecureEnv::ExceptionOccurred(/*[out]*/ jthrowable* result)
01243 {
01244        if (mJavaEnv == NULL || result == NULL)
01245               return NS_ERROR_NULL_POINTER;
01246     
01247     *result = mJavaEnv->ExceptionOccurred();
01248 
01249     return NS_OK;
01250 }
01251 
01252 NS_IMETHODIMP CSecureEnv::ExceptionDescribe(void)
01253 {
01254        if (mJavaEnv == NULL)
01255               return NS_ERROR_NULL_POINTER;
01256 
01257     mJavaEnv->ExceptionDescribe();
01258 
01259     return NS_OK;
01260 }
01261 
01262 
01263 NS_IMETHODIMP CSecureEnv::ExceptionClear(void)
01264 {
01265     mJavaEnv->ExceptionClear();
01266 
01267     return NS_OK;
01268 }
01269 
01270 
01271 NS_IMETHODIMP CSecureEnv::FatalError(/*[in]*/ const char* msg)
01272 {
01273     mJavaEnv->FatalError(msg);
01274 
01275     return NS_OK;
01276 }
01277 
01278 
01282 NS_IMETHODIMP CSecureEnv::NewGlobalRef(/*[in]*/  jobject localRef, 
01283                                         /*[out]*/ jobject* result)
01284 {
01285     if (result == NULL)
01286         return NS_ERROR_NULL_POINTER;
01287     
01288        // *result = mJavaEnv->NewGlobalRef(localRef);
01289        class NewGlobalRefMessage : public JavaMessage {
01290               jobject localRef;
01291               jobject* result;
01292        public:
01293               NewGlobalRefMessage(jobject localRef, jobject* result)
01294               {
01295                      this->localRef = localRef;
01296                      this->result = result;
01297               }
01298 
01299               virtual void execute(JNIEnv* env)
01300               {
01301                      *result = env->NewGlobalRef(localRef);
01302               }
01303        } msg(localRef, result);
01304        sendMessageToJava(&msg);
01305 
01306     return NS_OK;
01307 }
01308 
01309 
01310 NS_IMETHODIMP CSecureEnv::DeleteGlobalRef(/*[in]*/ jobject globalRef) 
01311 {
01312        JNIEnv* env = mSession->getCurrentEnv();
01313     env->DeleteGlobalRef(globalRef);
01314     return NS_OK;
01315 }
01316 
01320 class DeleteLocalRefMessage : public JavaMessage {
01321        jobject localRef;
01322 public:
01323        DeleteLocalRefMessage(jobject localRef)
01324        {
01325               this->localRef = localRef;
01326        }
01327 
01328        virtual void execute(JNIEnv* env)
01329        {
01330               env->DeleteLocalRef(localRef);
01331        }
01332 };
01333 
01334 NS_IMETHODIMP CSecureEnv::DeleteLocalRef(/*[in]*/ jobject obj)
01335 {
01336     mJavaEnv->DeleteLocalRef(obj);
01337     return NS_OK;
01338 }
01339 
01340 NS_IMETHODIMP CSecureEnv::IsSameObject(/*[in]*/  jobject obj1,
01341                                         /*[in]*/  jobject obj2,
01342                                         /*[out]*/ jboolean* result) 
01343 {
01344     if (mJavaEnv == NULL || result == NULL)
01345         return NS_ERROR_NULL_POINTER;
01346     
01347     *result = mJavaEnv->IsSameObject(obj1, obj2);
01348 
01349     return NS_OK;
01350 }
01351 
01352 
01353 NS_IMETHODIMP CSecureEnv::AllocObject(/*[in]*/  jclass clazz,
01354                                        /*[out]*/ jobject* result) 
01355 {
01356     if (mJavaEnv == NULL || result == NULL)
01357         return NS_ERROR_NULL_POINTER;
01358     
01359     *result = mJavaEnv->AllocObject(clazz);
01360 
01361     return NS_OK;
01362 }
01363 
01364 
01365 NS_IMETHODIMP CSecureEnv::GetObjectClass(/*[in]*/  jobject obj,
01366                                           /*[out]*/ jclass* result) 
01367 {
01368     if (mJavaEnv == NULL || result == NULL)
01369         return NS_ERROR_NULL_POINTER;
01370     
01371     *result = mJavaEnv->GetObjectClass(obj);
01372 
01373     return NS_OK;
01374 }
01375 
01376 
01377 NS_IMETHODIMP CSecureEnv::IsInstanceOf(/*[in]*/  jobject obj,
01378                                         /*[in]*/  jclass clazz,
01379                                         /*[out]*/ jboolean* result) 
01380 {
01381     if (mJavaEnv == NULL || result == NULL)
01382         return NS_ERROR_NULL_POINTER;
01383     
01384     *result = mJavaEnv->IsInstanceOf(obj, clazz);
01385 
01386     return NS_OK;
01387 }
01388 
01389 
01390 NS_IMETHODIMP CSecureEnv::GetMethodID(/*[in]*/  jclass clazz, 
01391                                        /*[in]*/  const char* name,
01392                                        /*[in]*/  const char* sig,
01393                                        /*[out]*/ jmethodID* result) 
01394 {
01395     if (result == NULL)
01396         return NS_ERROR_NULL_POINTER;
01397     
01398     // run this on the *CURRENT* thread.
01399     JNIEnv* env = mSession->getCurrentEnv();
01400     *result = env->GetMethodID(clazz, name, sig);
01401 
01402     return NS_OK;
01403 }
01404 
01405 
01406 NS_IMETHODIMP CSecureEnv::GetFieldID(/*[in]*/  jclass clazz, 
01407                                       /*[in]*/  const char* name,
01408                                       /*[in]*/  const char* sig,
01409                                       /*[out]*/ jfieldID* result) 
01410 {
01411     if (result == NULL)
01412         return NS_ERROR_NULL_POINTER;
01413     
01414     // run this on the *CURRENT* thread.
01415     JNIEnv* env = mSession->getCurrentEnv();
01416     *result = env->GetFieldID(clazz, name, sig);
01417 
01418     return NS_OK;
01419 }
01420 
01421 
01422 NS_IMETHODIMP CSecureEnv::GetStaticMethodID(/*[in]*/  jclass clazz, 
01423                                              /*[in]*/  const char* name,
01424                                              /*[in]*/  const char* sig,
01425                                              /*[out]*/ jmethodID* result)
01426 {
01427     if (result == NULL)
01428         return NS_ERROR_NULL_POINTER;
01429     
01430     // run this on the *CURRENT* thread.
01431     JNIEnv* env = mSession->getCurrentEnv();
01432     *result = env->GetStaticMethodID(clazz, name, sig);
01433 
01434     return NS_OK;
01435 }
01436 
01437 
01438 NS_IMETHODIMP CSecureEnv::GetStaticFieldID(/*[in]*/  jclass clazz, 
01439                                             /*[in]*/  const char* name,
01440                                             /*[in]*/  const char* sig,
01441                                             /*[out]*/ jfieldID* result) 
01442 {
01443     if (result == NULL)
01444         return NS_ERROR_NULL_POINTER;
01445     
01446     // run this on the *CURRENT* thread.
01447     JNIEnv* env = mSession->getCurrentEnv();
01448     *result = env->GetStaticFieldID(clazz, name, sig);
01449 
01450     return NS_OK;
01451 }
01452 
01456 NS_IMETHODIMP CSecureEnv::NewString(/*[in]*/  const jchar* unicode,
01457                                      /*[in]*/  jsize len,
01458                                      /*[out]*/ jstring* result) 
01459 {
01460     if (result == NULL)
01461         return NS_ERROR_NULL_POINTER;
01462     
01463        // *result = mJavaEnv->NewString(unicode, len);
01464        class NewStringMessage : public JavaMessage {
01465               const jchar* unicode;
01466               jsize len;
01467               jstring* result;
01468        public:
01469               NewStringMessage(const jchar* unicode, jsize len, jstring* result)
01470               {
01471                      this->unicode = unicode;
01472                      this->len = len;
01473                      this->result = result;
01474               }
01475 
01476               virtual void execute(JNIEnv* env)
01477               {
01478               *result = env->NewString(unicode, len);
01479               }
01480        } msg(unicode, len, result);
01481     sendMessageToJava(&msg);
01482 
01483     return NS_OK;
01484 }
01485 
01486 NS_IMETHODIMP CSecureEnv::GetStringLength(/*[in]*/  jstring str,
01487                                            /*[out]*/ jsize* result) 
01488 {
01489     if (mJavaEnv == NULL || result == NULL)
01490         return NS_ERROR_NULL_POINTER;
01491     
01492     *result = mJavaEnv->GetStringLength(str);
01493 
01494     return NS_OK;
01495 }
01496 
01497 NS_IMETHODIMP CSecureEnv::GetStringChars(/*[in]*/  jstring str,
01498                                           /*[in]*/  jboolean *isCopy,
01499                                           /*[out]*/ const jchar** result) 
01500 {
01501     if (mJavaEnv == NULL || result == NULL)
01502         return NS_ERROR_NULL_POINTER;
01503     
01504     *result = mJavaEnv->GetStringChars(str, isCopy);
01505 
01506     return NS_OK;
01507 }
01508 
01509 
01510 NS_IMETHODIMP CSecureEnv::ReleaseStringChars(/*[in]*/  jstring str,
01511                                               /*[in]*/  const jchar *chars) 
01512 {
01513     if (mJavaEnv == NULL)
01514         return NS_ERROR_NULL_POINTER;
01515     
01516     mJavaEnv->ReleaseStringChars(str, chars);
01517 
01518     return NS_OK;
01519 }
01520 
01521 
01522 NS_IMETHODIMP CSecureEnv::NewStringUTF(/*[in]*/  const char *utf,
01523                                         /*[out]*/ jstring* result) 
01524 {
01525     if (mJavaEnv == NULL || result == NULL)
01526         return NS_ERROR_NULL_POINTER;
01527     
01528        // *result = mJavaEnv->NewStringUTF(utf);
01529        class NewStringUTFMessage : public JavaMessage {
01530               const char *utf;
01531               jstring* result;
01532        public:
01533               NewStringUTFMessage(const char *utf, jstring* result)
01534               {
01535                      this->utf = utf;
01536                      this->result = result;
01537               }
01538 
01539               virtual void execute(JNIEnv* env)
01540               {
01541               *result = env->NewStringUTF(utf);
01542               }
01543        } msg(utf, result);
01544     sendMessageToJava(&msg);
01545 
01546     return NS_OK;
01547 }
01548 
01549 
01550 NS_IMETHODIMP CSecureEnv::GetStringUTFLength(/*[in]*/  jstring str,
01551                                               /*[out]*/ jsize* result) 
01552 {
01553     if (mJavaEnv == NULL || result == NULL)
01554         return NS_ERROR_NULL_POINTER;
01555     
01556     *result = mJavaEnv->GetStringUTFLength(str);
01557 
01558     return NS_OK;
01559 }
01560 
01561     
01562 NS_IMETHODIMP CSecureEnv::GetStringUTFChars(/*[in]*/  jstring str,
01563                                              /*[in]*/  jboolean *isCopy,
01564                                              /*[out]*/ const char** result) 
01565 {
01566     if (mJavaEnv == NULL || result == NULL)
01567         return NS_ERROR_NULL_POINTER;
01568     
01569     *result = mJavaEnv->GetStringUTFChars(str, isCopy);
01570 
01571     return NS_OK;
01572 }
01573 
01574 
01575 NS_IMETHODIMP CSecureEnv::ReleaseStringUTFChars(/*[in]*/  jstring str,
01576                                                  /*[in]*/  const char *chars) 
01577 {
01578     if (mJavaEnv == NULL)
01579         return NS_ERROR_NULL_POINTER;
01580     
01581     mJavaEnv->ReleaseStringUTFChars(str, chars);
01582 
01583     return NS_OK;
01584 }
01585 
01586 
01587 NS_IMETHODIMP CSecureEnv::GetArrayLength(/*[in]*/  jarray array,
01588                                           /*[out]*/ jsize* result) 
01589 {
01590     if (mJavaEnv == NULL || result == NULL)
01591         return NS_ERROR_NULL_POINTER;
01592     
01593     *result = mJavaEnv->GetArrayLength(array);
01594 
01595     return NS_OK;
01596 }
01597 
01598 NS_IMETHODIMP CSecureEnv::NewObjectArray(/*[in]*/  jsize len,
01599                                                                       /*[in]*/  jclass clazz,
01600                                                        /*[in]*/  jobject init,
01601                                                        /*[out]*/ jobjectArray* result)
01602 {
01603     if (mJavaEnv == NULL || result == NULL)
01604         return NS_ERROR_NULL_POINTER;
01605 
01606     *result = mJavaEnv->NewObjectArray(len, clazz, init);
01607 
01608     return NS_OK;
01609 }
01610 
01611 NS_IMETHODIMP CSecureEnv::GetObjectArrayElement(/*[in]*/  jobjectArray array,
01612                                                  /*[in]*/  jsize index,
01613                                                  /*[out]*/ jobject* result)
01614 {
01615     if (mJavaEnv == NULL || result == NULL)
01616         return NS_ERROR_NULL_POINTER;
01617 
01618     *result = mJavaEnv->GetObjectArrayElement(array, index);
01619 
01620     return NS_OK;
01621 }
01622 
01623 
01624 NS_IMETHODIMP CSecureEnv::SetObjectArrayElement(/*[in]*/  jobjectArray array,
01625                                                  /*[in]*/  jsize index,
01626                                                  /*[in]*/  jobject val) 
01627 {
01628     if (mJavaEnv == NULL)
01629         return NS_ERROR_NULL_POINTER;
01630 
01631     mJavaEnv->SetObjectArrayElement(array, index, val);
01632 
01633     return NS_OK;
01634 }
01635 
01636 NS_IMETHODIMP CSecureEnv::NewArray(/*[in]*/ jni_type element_type,
01637                                           /*[in]*/  jsize len,
01638                                           /*[out]*/ jarray* result) 
01639 {
01640     if (mJavaEnv == NULL || result == NULL)
01641         return NS_ERROR_NULL_POINTER;
01642 
01643     switch (element_type) {
01644     case jboolean_type:
01645         result = (jarray*) mJavaEnv->NewBooleanArray(len);
01646         break;
01647     case jbyte_type:
01648         result = (jarray*) mJavaEnv->NewByteArray(len);
01649         break;
01650     case jchar_type:
01651         result = (jarray*) mJavaEnv->NewCharArray(len);
01652         break;
01653     case jshort_type:
01654         result = (jarray*) mJavaEnv->NewShortArray(len);
01655         break;
01656     case jint_type:
01657         result = (jarray*) mJavaEnv->NewIntArray(len);
01658         break;
01659     case jlong_type:
01660         result = (jarray*) mJavaEnv->NewLongArray(len);
01661         break;
01662     case jfloat_type:
01663         result = (jarray*) mJavaEnv->NewFloatArray(len);
01664         break;
01665     case jdouble_type:
01666         result = (jarray*) mJavaEnv->NewDoubleArray(len);
01667         break;
01668     default:
01669         return NS_ERROR_FAILURE;
01670     }
01671 
01672     return NS_OK;
01673 }
01674 
01675 
01676 NS_IMETHODIMP CSecureEnv::GetArrayElements(/*[in]*/  jni_type type,
01677                                             /*[in]*/  jarray array,
01678                                             /*[in]*/  jboolean *isCopy,
01679                                             /*[out]*/ void* result)
01680 {
01681     if (mJavaEnv == NULL || result == NULL)
01682         return NS_ERROR_NULL_POINTER;
01683 
01684     switch (type) {
01685        case jboolean_type:
01686            result = (void*) mJavaEnv->GetBooleanArrayElements((jbooleanArray)array, isCopy);
01687            break;
01688        case jbyte_type:
01689            result = (void*) mJavaEnv->GetByteArrayElements((jbyteArray)array, isCopy);
01690            break;
01691        case jchar_type:
01692            result = (void*) mJavaEnv->GetCharArrayElements((jcharArray)array, isCopy);
01693            break;
01694        case jshort_type:
01695            result = (void*) mJavaEnv->GetShortArrayElements((jshortArray)array, isCopy);
01696            break;
01697        case jint_type:
01698            result = (void*) mJavaEnv->GetIntArrayElements((jintArray)array, isCopy);
01699            break;
01700        case jlong_type:
01701            result = (void*) mJavaEnv->GetLongArrayElements((jlongArray)array, isCopy);
01702            break;
01703        case jfloat_type:
01704            result = (void*) mJavaEnv->GetFloatArrayElements((jfloatArray)array, isCopy);
01705            break;
01706        case jdouble_type:
01707            result = (void*) mJavaEnv->GetDoubleArrayElements((jdoubleArray)array, isCopy);
01708            break;
01709        default:
01710            return NS_ERROR_FAILURE;
01711        }
01712 
01713     return NS_OK;
01714 }
01715 
01716 
01717 NS_IMETHODIMP CSecureEnv::ReleaseArrayElements(/*[in]*/ jni_type type,
01718                                                 /*[in]*/ jarray array,
01719                                                 /*[in]*/ void *elems,
01720                                                 /*[in]*/ jint mode) 
01721 {
01722        if (mJavaEnv == NULL)
01723               return NS_ERROR_NULL_POINTER;
01724        
01725        switch (type)
01726        {
01727        case jboolean_type:
01728               mJavaEnv->ReleaseBooleanArrayElements((jbooleanArray)array, (jboolean*)elems, mode);
01729               break;
01730        case jbyte_type:
01731               mJavaEnv->ReleaseByteArrayElements((jbyteArray)array, (jbyte*)elems, mode);
01732               break;
01733        case jchar_type:
01734               mJavaEnv->ReleaseCharArrayElements((jcharArray)array, (jchar*)elems, mode);
01735               break;
01736        case jshort_type:
01737               mJavaEnv->ReleaseShortArrayElements((jshortArray)array, (jshort*)elems, mode);
01738               break;
01739        case jint_type:
01740               mJavaEnv->ReleaseIntArrayElements((jintArray)array, (jint*)elems, mode);
01741               break;
01742        case jlong_type:
01743               mJavaEnv->ReleaseLongArrayElements((jlongArray)array, (jlong*)elems, mode);
01744               break;
01745        case jfloat_type:
01746               mJavaEnv->ReleaseFloatArrayElements((jfloatArray)array, (jfloat*)elems, mode);
01747               break;
01748        case jdouble_type:
01749               mJavaEnv->ReleaseDoubleArrayElements((jdoubleArray)array, (jdouble*)elems, mode);
01750               break;
01751        default:
01752               return NS_ERROR_FAILURE;
01753        }
01754 
01755     return NS_OK;
01756 }
01757 
01758 NS_IMETHODIMP CSecureEnv::GetArrayRegion(/*[in]*/  jni_type type,
01759                                           /*[in]*/  jarray array,
01760                                           /*[in]*/  jsize start,
01761                                           /*[in]*/  jsize len,
01762                                           /*[out]*/ void* buf)
01763 {
01764     if (mJavaEnv == NULL || buf == NULL)
01765         return NS_ERROR_NULL_POINTER;
01766 
01767     switch (type) {
01768     case jboolean_type:
01769         mJavaEnv->GetBooleanArrayRegion((jbooleanArray)array, start, len, (jboolean*)buf);
01770         break;
01771     case jbyte_type:
01772         mJavaEnv->GetByteArrayRegion((jbyteArray)array, start, len, (jbyte*)buf);
01773         break;
01774     case jchar_type:
01775         mJavaEnv->GetCharArrayRegion((jcharArray)array, start, len, (jchar*)buf);
01776         break;
01777     case jshort_type:
01778         mJavaEnv->GetShortArrayRegion((jshortArray)array, start, len, (jshort*)buf);
01779         break;
01780     case jint_type:
01781         mJavaEnv->GetIntArrayRegion((jintArray)array, start, len, (jint*)buf);
01782         break;
01783     case jlong_type:
01784         mJavaEnv->GetLongArrayRegion((jlongArray)array, start, len, (jlong*)buf);
01785         break;
01786     case jfloat_type:
01787         mJavaEnv->GetFloatArrayRegion((jfloatArray)array, start, len, (jfloat*)buf);
01788         break;
01789     case jdouble_type:
01790         mJavaEnv->GetDoubleArrayRegion((jdoubleArray)array, start, len, (jdouble*)buf);
01791         break;
01792     default:
01793         return NS_ERROR_FAILURE;
01794     }
01795 
01796     return NS_OK;
01797 }
01798 
01799 
01800 NS_IMETHODIMP CSecureEnv::SetArrayRegion(/*[in]*/  jni_type type,
01801                                           /*[in]*/  jarray array,
01802                                           /*[in]*/  jsize start,
01803                                           /*[in]*/  jsize len,
01804                                           /*[in]*/  void* buf) 
01805 {
01806     if (mJavaEnv == NULL || buf == NULL)
01807         return NS_ERROR_NULL_POINTER;
01808 
01809     switch (type) {
01810     case jboolean_type:
01811         mJavaEnv->SetBooleanArrayRegion((jbooleanArray)array, start, len, (jboolean*)buf);
01812         break;
01813     case jbyte_type:
01814         mJavaEnv->SetByteArrayRegion((jbyteArray)array, start, len, (jbyte*)buf);
01815         break;
01816     case jchar_type:
01817         mJavaEnv->SetCharArrayRegion((jcharArray)array, start, len, (jchar*)buf);
01818         break;
01819     case jshort_type:
01820         mJavaEnv->SetShortArrayRegion((jshortArray)array, start, len, (jshort*)buf);
01821         break;
01822     case jint_type:
01823         mJavaEnv->SetIntArrayRegion((jintArray)array, start, len, (jint*)buf);
01824         break;
01825     case jlong_type:
01826         mJavaEnv->SetLongArrayRegion((jlongArray)array, start, len, (jlong*)buf);
01827         break;
01828     case jfloat_type:
01829         mJavaEnv->SetFloatArrayRegion((jfloatArray)array, start, len, (jfloat*)buf);
01830         break;
01831     case jdouble_type:
01832         mJavaEnv->SetDoubleArrayRegion((jdoubleArray)array, start, len, (jdouble*)buf);
01833         break;
01834     default:
01835         return NS_ERROR_FAILURE;
01836     }
01837 
01838     return NS_OK;
01839 }
01840 
01841 
01842 NS_IMETHODIMP CSecureEnv::RegisterNatives(/*[in]*/  jclass clazz,
01843                                            /*[in]*/  const JNINativeMethod *methods,
01844                                            /*[in]*/  jint nMethods,
01845                                            /*[out]*/ jint* result) 
01846 {
01847     if (mJavaEnv == NULL || result == NULL)
01848         return NS_ERROR_NULL_POINTER;
01849 
01850     *result = mJavaEnv->RegisterNatives(clazz, methods, nMethods);
01851 
01852     return NS_OK;
01853 }
01854 
01855 
01856 NS_IMETHODIMP CSecureEnv::UnregisterNatives(/*[in]*/  jclass clazz,
01857                                              /*[out]*/ jint* result) 
01858 {
01859     if (mJavaEnv == NULL || result == NULL)
01860         return NS_ERROR_NULL_POINTER;
01861 
01862     *result = mJavaEnv->UnregisterNatives(clazz);
01863 
01864     return NS_OK;
01865 }
01866 
01867 
01868 NS_IMETHODIMP CSecureEnv::MonitorEnter(/*[in]*/  jobject obj,
01869                                         /*[out]*/ jint* result) 
01870 {
01871     if (mJavaEnv == NULL || result == NULL)
01872         return NS_ERROR_NULL_POINTER;
01873 
01874        // *result = mJavaEnv->MonitorEnter(obj);
01875        class MonitorEnterMessage : public JavaMessage {
01876               jobject obj;
01877               jint* result;
01878        public:
01879               MonitorEnterMessage(jobject obj, jint* result)
01880               {
01881                      this->obj = obj;
01882                      this->result = result;
01883               }
01884 
01885               virtual void execute(JNIEnv* env)
01886               {
01887                      *result = env->MonitorEnter(obj);
01888               }
01889        } msg(obj, result);
01890        sendMessageToJava(&msg);
01891 
01892     return NS_OK;
01893 }
01894 
01895 
01896 NS_IMETHODIMP CSecureEnv::MonitorExit(/*[in]*/  jobject obj,
01897                                        /*[out]*/ jint* result)
01898 {
01899     if (mJavaEnv == NULL || result == NULL)
01900         return NS_ERROR_NULL_POINTER;
01901 
01902        // *result = mJavaEnv->MonitorExit(obj);
01903        class MonitorExitMessage : public JavaMessage {
01904               jobject obj;
01905               jint* result;
01906        public:
01907               MonitorExitMessage(jobject obj, jint* result)
01908               {
01909                      this->obj = obj;
01910                      this->result = result;
01911               }
01912 
01913               virtual void execute(JNIEnv* env)
01914               {
01915                      *result = env->MonitorExit(obj);
01916               }
01917        } msg(obj, result);
01918        sendMessageToJava(&msg);
01919 
01920     return NS_OK;
01921 }
01922 
01923 NS_IMETHODIMP CSecureEnv::GetJavaVM(/*[in]*/  JavaVM **vm,
01924                                      /*[out]*/ jint* result)
01925 {
01926     if (mJavaEnv == NULL || result == NULL)
01927         return NS_ERROR_NULL_POINTER;
01928 
01929     *result = mJavaEnv->GetJavaVM(vm);
01930 
01931     return NS_OK;
01932 }
01933 
01938 void CSecureEnv::messageLoop(JNIEnv* env, JavaMessage* msg, JavaMessageQueue* sendQueue, JavaMessageQueue* receiveQueue, Boolean busyWaiting)
01939 {
01940        // put the message in the send queue, and wait for a reply.
01941        sendQueue->putMessage(msg);
01942        sendQueue->notify();
01943        JavaMessage* replyMsg = receiveQueue->getMessage();
01944        for (;;) {
01945               // Fully synchronized approach.
01946               if (replyMsg != NULL) {
01947                      if (replyMsg == msg)
01948                             break;
01949                      // must be a message that needs executing.
01950                      replyMsg->execute(env);
01951                      sendQueue->putMessage(replyMsg);
01952                      sendQueue->notify();
01953                      // notify can cause a yield, so look again.
01954                      replyMsg = receiveQueue->getMessage();
01955                      if (replyMsg != NULL)
01956                             continue;
01957               }
01958               // when busy waiting, must give time to browser between timed waits.
01959               if (busyWaiting) {
01960                      receiveQueue->wait(kDefaultJMTime);
01961                      replyMsg = receiveQueue->getMessage();
01962                      if (replyMsg != NULL)
01963                             continue;
01964                      // mSession->lock();
01965                      mThreadManager->Sleep();
01966                      // mSession->unlock();
01967               } else {
01968                      // wait for a message to arrive.
01969                      receiveQueue->wait();
01970               }
01971               replyMsg = receiveQueue->getMessage();
01972        }
01973 }
01974 
01975 CSecureEnv* GetSecureJNI(JNIEnv* env, jobject thread)
01976 {
01977        CSecureEnv* secureJNI = NULL;
01978        
01979        jclass threadClass = env->GetObjectClass(thread);
01980        if (threadClass != NULL) {
01981               jfieldID fSecureEnvField = env->GetFieldID(threadClass, "fSecureEnv", "I");
01982               if (fSecureEnvField != NULL) {
01983                      secureJNI = (CSecureEnv*) env->GetIntField(thread, fSecureEnvField);
01984               } else {
01985                      env->ExceptionClear();
01986               }
01987               env->DeleteLocalRef(threadClass);
01988        }
01989        
01990        return secureJNI;
01991 }