Bug 807078 - Clean up message listeners before closing window. r=benadida, a=blocking-basecamp
authorJed Parsons <jparsons@mozilla.com>
Fri, 02 Nov 2012 16:11:51 -0400
changeset 113928 ea28d6b8dbd80496ca342573a4c2cb410a25e5b3
parent 113927 d130df80561dabe0080d0ef3bde9e16471578b45
child 113929 1ad4fc08462dd7321a2a2a44a70ef7b1f966b658
push id2569
push userryanvm@gmail.com
push dateSat, 03 Nov 2012 14:43:40 +0000
treeherdermozilla-aurora@852c98a08997 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbenadida, blocking-basecamp
bugs807078
milestone18.0a2
Bug 807078 - Clean up message listeners before closing window. r=benadida, a=blocking-basecamp
b2g/chrome/content/identity.js
b2g/components/SignInToWebsite.jsm
--- a/b2g/chrome/content/identity.js
+++ b/b2g/chrome/content/identity.js
@@ -54,30 +54,23 @@ var func = null;
  *
  *   method:             one of 'login', 'logout', 'ready'
  *   assertion:          optional assertion
  */
 function identityCall(message) {
   sendAsyncMessage(kIdentityControllerDoMethod, message);
 }
 
-function identityFinished() {
-  log("identity finished.  closing dialog");
-  closeIdentityDialog(function notifySuccess() {
-    // get ready for next call with a reinit
-    func = null; options = null;
-
-    sendAsyncMessage(kIdentityDelegateFinished);
-  });
-}
-
 /*
- * Notify the UI to close the dialog and return to the caller application
+ * To close the dialog, we first tell the gecko SignInToWebsite manager that it
+ * can clean up.  Then we tell the gaia component that we are finished.  It is
+ * necessary to notify gecko first, so that the message can be sent before gaia
+ * destroys our context.
  */
-function closeIdentityDialog(aCallback) {
+function closeIdentityDialog() {
   let randomId = uuidgen.generateUUID().toString();
   let id = kReceivedIdentityAssertion + "-" + randomId;
   let browser = Services.wm.getMostRecentWindow("navigator:browser");
 
   let detail = {
     type: kReceivedIdentityAssertion,
     id: id,
     showUI: showUI
@@ -89,16 +82,21 @@ function closeIdentityDialog(aCallback) 
   content.addEventListener("mozContentEvent", function closeIdentityDialogFinished(evt) {
     content.removeEventListener("mozContentEvent", closeIdentityDialogFinished);
 
     if (evt.detail.id == id && aCallback) {
       aCallback();
     }
   });
 
+  // tell gecko we're done.  fire and forget.
+  func = null; options = null;
+  sendAsyncMessage(kIdentityDelegateFinished);
+
+  // tell gaia to shut us down
   browser.shell.sendChromeEvent(detail);
 }
 
 /*
  * doInternalWatch - call the internal.watch api and relay the results
  * up to the controller.
  */
 function doInternalWatch() {
@@ -106,17 +104,17 @@ function doInternalWatch() {
   if (options && isLoaded) {
     log("internal watch options:", options);
     let BrowserID = content.wrappedJSObject.BrowserID;
     BrowserID.internal.watch(function(aParams) {
         log("sending watch method message:", aParams.method);
         identityCall(aParams);
         if (aParams.method === "ready") {
           log("watch finished.");
-          identityFinished();
+          closeIdentityDialog();
         }
       },
       JSON.stringify({loggedInUser: options.loggedInUser, origin: options.origin}),
       function(...things) {
         log("internal: ", things);
       }
     );
   }
@@ -127,30 +125,30 @@ function doInternalRequest() {
   if (options && isLoaded) {
     content.wrappedJSObject.BrowserID.internal.get(
       options.origin,
       function(assertion) {
         if (assertion) {
           log("request -> assertion, so do login");
           identityCall({method:'login',assertion:assertion});
         }
-        identityFinished();
+        closeIdentityDialog();
       },
       options);
   }
 }
 
 function doInternalLogout(aOptions) {
   log("doInternalLogout:", (options && isLoaded));
   if (options && isLoaded) {
     let BrowserID = content.wrappedJSObject.BrowserID;
     log("logging you out of ", options.origin);
     BrowserID.internal.logout(options.origin, function() {
       identityCall({method:'logout'});
-      identityFinished();
+      closeIdentityDialog();
     });
   }
 }
 
 addEventListener("DOMContentLoaded", function(e) {
   content.addEventListener("load", function(e) {
     isLoaded = true;
      // bring da func
--- a/b2g/components/SignInToWebsite.jsm
+++ b/b2g/components/SignInToWebsite.jsm
@@ -284,21 +284,21 @@ let SignInToWebsiteController = {
   },
 
   /*
    * options:    method          required - name of method to invoke
    *             assertion       optional
    */
   _makeDoMethodCallback: function SignInToWebsiteController__makeDoMethodCallback(aRpId) {
     return function SignInToWebsiteController_methodCallback(aOptions) {
-      log("doMethod:", aOptions);
       let message = aOptions.json;
       if (typeof message === 'string') {
         message = JSON.parse(message);
       }
+      log("doMethod:", message.method);
       switch(message.method) {
         case "ready":
           IdentityService.doReady(aRpId);
           break;
 
         case "login":
            IdentityService.doLogin(aRpId, message.assertion);
           break;