Bug 409280, nsIProtectedAuthThread is not embedding friendly Patch contributed by Christian Persch (GNOME) r=kengert, blocking1.9=mtschrep

This commit is contained in:
kaie@kuix.de 2008-01-15 14:41:52 -08:00
parent 742d0427ff
commit 8b4324d92b
4 changed files with 65 additions and 40 deletions

View File

@ -53,7 +53,14 @@ function onLoad()
setCursor("wait");
protectedAuthThread.login(window);
var obs = {
observe : function protectedAuthListenerObserve(subject, topic, data) {
if (topic == "operation-completed")
window.close();
}
};
protectedAuthThread.login(obs);
} catch (exception)
{

View File

@ -35,14 +35,15 @@
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsIDOMWindowInternal.idl"
#include "nsIObserver.idl"
#include "nsIPKCS11Slot.idl"
/**
* nsIProtectedAuthThread
* This is used to communicate with the thread login on to
* a token with CKF_PROTECTED_AUTHENTICATION_PATH set.
*/
[scriptable, uuid(45334489-3d30-47c6-920b-0a55a313aebf)]
[scriptable, uuid(4bb27cb7-8984-4cee-8ce7-9b014c3d091b)]
interface nsIProtectedAuthThread : nsISupports
{
/**
@ -51,13 +52,22 @@ interface nsIProtectedAuthThread : nsISupports
* call this method as soon as the message to the user is
* displayed. This will trigger login operation. No user
* cancellation is possible during login operation.
*
* When the login is done, the observe method of @observer will
* be called on the UI thread with a topic of "login-finished"
* and null data and subject.
*/
void login(in nsIDOMWindowInternal dialog);
void login(in nsIObserver observer);
/**
* The PKCS11 slot
*/
readonly attribute nsIPKCS11Slot slot;
/**
* Gets token to be logged in name.
*/
wstring getTokenName();
AString getTokenName();
};
%{ C++

View File

@ -36,9 +36,11 @@
#include "pk11func.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsProxiedService.h"
#include "nsString.h"
#include "nsReadableUtils.h"
#include "nsPKCS11Slot.h"
#include "nsProtectedAuthThread.h"
NS_IMPL_THREADSAFE_ISUPPORTS1(nsProtectedAuthThread, nsIProtectedAuthThread)
@ -51,9 +53,8 @@ static void PR_CALLBACK nsProtectedAuthThreadRunner(void *arg)
nsProtectedAuthThread::nsProtectedAuthThread()
: mMutex(nsnull)
, mStatusDialogPtr(nsnull)
, mIAmRunning(PR_FALSE)
, mStatusDialogClosed(PR_FALSE)
, mStatusObserverNotified(PR_FALSE)
, mLoginReady(PR_FALSE)
, mThreadHandle(nsnull)
, mSlot(0)
@ -67,31 +68,27 @@ nsProtectedAuthThread::~nsProtectedAuthThread()
{
if (mMutex)
PR_DestroyLock(mMutex);
if (mStatusDialogPtr)
{
NS_RELEASE(mStatusDialogPtr);
}
}
NS_IMETHODIMP nsProtectedAuthThread::Login(nsIDOMWindowInternal *statusDialog)
NS_IMETHODIMP nsProtectedAuthThread::Login(nsIObserver *aObserver)
{
if (!mMutex)
return NS_ERROR_FAILURE;
NS_ENSURE_ARG(aObserver);
if (!statusDialog )
if (!mMutex)
return NS_ERROR_FAILURE;
if (!mSlot)
// We need pointer to the slot
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMWindowInternal> wi;
NS_GetProxyForObject( NS_PROXY_TO_MAIN_THREAD,
nsIDOMWindowInternal::GetIID(),
statusDialog,
nsCOMPtr<nsIObserver> observerProxy;
nsresult rv = NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
NS_GET_IID(nsIObserver),
aObserver,
NS_PROXY_SYNC | NS_PROXY_ALWAYS,
getter_AddRefs(wi));
getter_AddRefs(observerProxy));
if (NS_FAILED(rv))
return rv;
PR_Lock(mMutex);
@ -100,10 +97,7 @@ NS_IMETHODIMP nsProtectedAuthThread::Login(nsIDOMWindowInternal *statusDialog)
return NS_OK;
}
mStatusDialogPtr = wi;
NS_ADDREF(mStatusDialogPtr);
wi = 0;
observerProxy.swap(mStatusObserver);
mIAmRunning = PR_TRUE;
mThreadHandle = PR_CreateThread(PR_USER_THREAD, nsProtectedAuthThreadRunner, static_cast<void*>(this),
@ -118,18 +112,31 @@ NS_IMETHODIMP nsProtectedAuthThread::Login(nsIDOMWindowInternal *statusDialog)
return NS_OK;
}
NS_IMETHODIMP nsProtectedAuthThread::GetTokenName(PRUnichar **_retval)
NS_IMETHODIMP nsProtectedAuthThread::GetTokenName(nsAString &_retval)
{
PR_Lock(mMutex);
// Get token name
*_retval = UTF8ToNewUnicode(nsDependentCString(PK11_GetTokenName(mSlot)));
CopyUTF8toUTF16(nsDependentCString(PK11_GetTokenName(mSlot)), _retval);
PR_Unlock(mMutex);
return NS_OK;
}
NS_IMETHODIMP nsProtectedAuthThread::GetSlot(nsIPKCS11Slot **_retval)
{
PR_Lock(mMutex);
nsRefPtr<nsPKCS11Slot> slot = new nsPKCS11Slot(mSlot);
PR_Unlock(mMutex);
if (!slot)
return NS_ERROR_OUT_OF_MEMORY;
return CallQueryInterface (slot.get(), _retval);
}
void nsProtectedAuthThread::SetParams(PK11SlotInfo* aSlot)
{
@ -151,7 +158,7 @@ void nsProtectedAuthThread::Run(void)
// it is harmless here
mLoginResult = PK11_CheckUserPassword(mSlot, 0);
nsIDOMWindowInternal *windowToClose = 0;
nsIObserver *observer = nsnull;
PR_Lock(mMutex);
@ -165,18 +172,18 @@ void nsProtectedAuthThread::Run(void)
mSlot = 0;
}
if (!mStatusDialogClosed)
if (!mStatusObserverNotified)
{
windowToClose = mStatusDialogPtr;
observer = mStatusObserver;
}
mStatusDialogPtr = 0;
mStatusDialogClosed = PR_TRUE;
mStatusObserver = nsnull;
mStatusObserverNotified = PR_TRUE;
PR_Unlock(mMutex);
if (windowToClose)
windowToClose->Close();
if (observer)
observer->Observe(nsnull, "operation-completed", nsnull);
}
void nsProtectedAuthThread::Join()

View File

@ -37,6 +37,7 @@
#ifndef NSPROTECTEDAUTHTHREAD_H_
#define NSPROTECTEDAUTHTHREAD_H_
#include <nsCOMPtr.h>
#include "keyhi.h"
#include "nspr.h"
@ -47,10 +48,10 @@ class nsProtectedAuthThread : public nsIProtectedAuthThread
private:
PRLock *mMutex;
nsIDOMWindowInternal* mStatusDialogPtr;
nsCOMPtr<nsIObserver> mStatusObserver;
PRBool mIAmRunning;
PRBool mStatusDialogClosed;
PRBool mStatusObserverNotified;
PRBool mLoginReady;
PRThread *mThreadHandle;