Bug 1456260 - Support concurrent GeckoSession.saveState() calls. r=jchen
authorDylan Roeh <droeh@mozilla.com>
Fri, 27 Apr 2018 10:44:26 -0500
changeset 416052 62eb4b67db486bdb546085592bfcce517984a80b
parent 416051 315e0039f7e475c8a67f743cff7ef8804946f13f
child 416053 f7289b97cdf13377957a233452da38784970592f
push id102714
push userdroeh@mozilla.com
push dateFri, 27 Apr 2018 21:12:45 +0000
treeherdermozilla-inbound@62eb4b67db48 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjchen
bugs1456260
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1456260 - Support concurrent GeckoSession.saveState() calls. r=jchen
mobile/android/chrome/geckoview/GeckoViewContent.js
mobile/android/modules/geckoview/GeckoViewContent.jsm
--- a/mobile/android/chrome/geckoview/GeckoViewContent.js
+++ b/mobile/android/chrome/geckoview/GeckoViewContent.js
@@ -180,20 +180,20 @@ class GeckoViewContent extends GeckoView
           }
         }, 500);
         break;
       }
 
       case "GeckoView:SaveState":
         if (this._savedState) {
           // Short circuit and return the pending state if we're in the process of restoring
-          sendAsyncMessage("GeckoView:SaveStateFinish", {state: JSON.stringify(this._savedState)});
+          sendAsyncMessage("GeckoView:SaveStateFinish", {state: JSON.stringify(this._savedState), id: aMsg.data.id});
         } else {
           let state = this.collectSessionState();
-          sendAsyncMessage("GeckoView:SaveStateFinish", {state: JSON.stringify(state)});
+          sendAsyncMessage("GeckoView:SaveStateFinish", {state: JSON.stringify(state), id: aMsg.data.id});
         }
         break;
 
       case "GeckoView:RestoreState":
         this._savedState = JSON.parse(aMsg.data.state);
 
         if (this._savedState.history) {
           let restoredHistory = SessionHistory.restore(docShell, this._savedState.history);
--- a/mobile/android/modules/geckoview/GeckoViewContent.jsm
+++ b/mobile/android/modules/geckoview/GeckoViewContent.jsm
@@ -67,22 +67,23 @@ class GeckoViewContent extends GeckoView
           this.browser.docShellIsActive = true;
         } else {
           this.browser.removeAttribute("primary");
           this.browser.docShellIsActive = false;
           this.browser.blur();
         }
         break;
       case "GeckoView:SaveState":
-        if (this._saveStateCallback) {
-          aCallback.onError();
-        } else {
-          this.messageManager.sendAsyncMessage("GeckoView:SaveState");
-          this._saveStateCallback = aCallback;
+        if (!this._saveStateCallbacks) {
+          this._saveStateCallbacks = new Map();
+          this._saveStateNextId = 0;
         }
+        this._saveStateCallbacks.set(this._saveStateNextId, aCallback);
+        this.messageManager.sendAsyncMessage("GeckoView:SaveState", {id: this._saveStateNextId})
+        this._saveStateNextId++;
         break;
       case "GeckoView:RestoreState":
         this.messageManager.sendAsyncMessage("GeckoView:RestoreState", {state: aData.state});
         break;
     }
   }
 
   // DOM event handler
@@ -113,16 +114,18 @@ class GeckoViewContent extends GeckoView
                    .remoteFrameFullscreenReverted();
         break;
       case "GeckoView:DOMFullscreenRequest":
         this.window.QueryInterface(Ci.nsIInterfaceRequestor)
                    .getInterface(Ci.nsIDOMWindowUtils)
                    .remoteFrameFullscreenChanged(aMsg.target);
         break;
       case "GeckoView:SaveStateFinish":
-        if (this._saveStateCallback) {
-          this._saveStateCallback.onSuccess(aMsg.data.state);
-          delete this._saveStateCallback;
+        if (!this._saveStateCallbacks || !this._saveStateCallbacks.has(aMsg.data.id)) {
+          warn `Failed to save state due to missing callback`;
+          return;
         }
+        this._saveStateCallbacks.get(aMsg.data.id).onSuccess(aMsg.data.state);
+        this._saveStateCallbacks.delete(aMsg.data.id);
         break;
     }
   }
 }