Index: build/chrome/cackey.js ================================================================== --- build/chrome/cackey.js +++ build/chrome/cackey.js @@ -146,11 +146,11 @@ if (messageEvent.data.command == "init" && messageEvent.data.status == "success") { if (GoogleSmartCard.IS_DEBUG_BUILD) { console.log("[cackey] Initialization completed, resending any queued messages"); } - cackeyInitPCSCCompleted(); + cackeyInitPCSCCompleted("success"); } if (messageEvent.data.id == null) { return; } @@ -225,10 +225,11 @@ * Register a handler to handle the window being closed without * having sent anything */ pinWindow.onClosed.addListener(function() { var messageIdx; + var chromeCallback; pinWindowPreviousHandle = null; for (messageIdx = 0; messageIdx < cackeyMessagesToRetry.length; messageIdx++) { var tmpMessageEvent; @@ -246,13 +247,28 @@ cackeyMessageIncoming(tmpMessageEvent); } else { tmpMessageEvent.data.originalrequest.pin = pinWindowPINValue; cackeyCertificateToPINMap[cackeyCertificateToPINID(tmpMessageEvent.data.originalrequest.certificate)] = pinWindowPINValue; + + chromeCallback = null; + if (tmpMessageEvent.data.id) { + if (cackeyOutstandingCallbacks) { + chromeCallback = cackeyOutstandingCallbacks[tmpMessageEvent.data.id]; + } + } cackeyInitPCSC(function() { cackeyHandle.postMessage(tmpMessageEvent.data.originalrequest); + }, function() { + if (chromeCallback) { + chromeCallback(); + } + + if (tmpMessageEvent.data.id && cackeyOutstandingCallbacks[tmpMessageEvent.data.id]) { + delete cackeyOutstandingCallbacks[tmpMessageEvent.data.id]; + } }); } } @@ -334,11 +350,11 @@ cackeyOutstandingCallbacks[callbackId] = chromeCallback; if (GoogleSmartCard.IS_DEBUG_BUILD) { console.log("[cackey] Thrown."); } - }); + }, chromeCallback); return; } /* @@ -404,11 +420,11 @@ cackeyOutstandingCallbacks[callbackId] = chromeCallback; if (GoogleSmartCard.IS_DEBUG_BUILD) { console.log("[cackey] Thrown."); } - }); + }, chromeCallback); return; } /* @@ -499,34 +515,56 @@ setTimeout(cackeyInit, 30000); return; } -function cackeyInitPCSCCompleted() { +function cackeyInitPCSCCompleted(state) { var idx; - cackeyPCSCHandleUsable = true; + console.log("[cackey] Connection completed (state = \"" + state + "\"), sending queued events: " + cackeyCallbackAfterInit.length); + + switch (state) { + case "success": + cackeyPCSCHandleUsable = true; + + break; + case "failure": + cackeyPCSCHandleUsable = false; + + break; + } for (idx = 0; idx < cackeyCallbackAfterInit.length; idx++) { if (!cackeyCallbackAfterInit[idx]) { continue; } - cackeyCallbackAfterInit[idx](); + switch (state) { + case "success": + (cackeyCallbackAfterInit[idx].successCallback)(); + + break; + case "failure": + (cackeyCallbackAfterInit[idx].failureCallback)(); + + break; + } } delete cackeyCallbackAfterInit; cackeyCallbackAfterInit = []; + + console.log("[cackey] All queued events processed"); return; } /* * Initialize the PCSC connection */ -function cackeyInitPCSC(callbackAfterInit) { +function cackeyInitPCSC(callbackAfterInit, callbackInitFailed) { /* * Start the Google PCSC Interface */ console.log("[cackey] cackeyInitPCSC() called"); @@ -533,11 +571,11 @@ /* * Queue this callback to be completed when initialization is complete */ if (callbackAfterInit) { - cackeyCallbackAfterInit.push(callbackAfterInit); + cackeyCallbackAfterInit.push({"successCallback": callbackAfterInit, "failureCallback": callbackInitFailed}); } /* * No additional work is required */ @@ -544,11 +582,11 @@ if (cackeyPCSCHandle) { console.log("[cackey] PCSC handle is already valid, nothing to do."); if (cackeyPCSCHandleUsable) { - cackeyInitPCSCCompleted(); + cackeyInitPCSCCompleted("success"); } return; } @@ -691,10 +729,12 @@ * Register a handler for dealing with the PCSC port being disconnected */ oldOnPortDisconnectedFunction = GoogleSmartCard.Pcsc.prototype.onPortDisconnected_; GoogleSmartCard.Pcsc.prototype.onPortDisconnected_ = function() { oldOnPortDisconnectedFunction.apply(this); + + cackeyInitPCSCCompleted("failure"); cackeyRestart(); return; }; Index: build/chrome/ui.js ================================================================== --- build/chrome/ui.js +++ build/chrome/ui.js @@ -44,10 +44,18 @@ } else { displayCerts(htmlObject, globalCerts); } parentWindow.cackeyListCertificates(function(certs) { + /* + * If there is an error then we are invoked with no certs + * parameter at all, fake one. + */ + if (!certs) { + certs = []; + } + globalCerts = certs; displayCerts(htmlObject, certs); });