Bug 1673617 - Refactor how session restore works with SHIP, r=nika

With mods from kashav's last Try run

Differential Revision: https://phabricator.services.mozilla.com/D99461
This commit is contained in:
Randell Jesup
2021-01-19 17:21:34 +00:00
parent 2d810526d6
commit fb8153a8f2
7 changed files with 553 additions and 494 deletions

View File

@@ -95,9 +95,16 @@ class EventListener extends Handler {
}
if (this.contentRestoreInitialized) {
// Restore the form data and scroll position. If we're not currently
// restoring a tab state then this call will simply be a noop.
this.contentRestore.restoreDocument();
// Restore the form data and scroll position (if we're restoring a
// document).
if (
this.contentRestore.restoreDocument() &&
Services.appinfo.sessionHistoryInParent
) {
this.mm.sendAsyncMessage("SessionStore:restoreTabContentComplete", {
epoch: this.store.epoch,
});
}
}
}
}
@@ -503,14 +510,13 @@ class MessageQueue extends Handler {
*/
const MESSAGES = [
"SessionStore:restoreHistory",
"SessionStore:finishRestoreHistory",
"SessionStore:OnHistoryReload",
"SessionStore:OnHistoryNewEntry",
"SessionStore:restoreDocShellState",
"SessionStore:restoreTabContent",
"SessionStore:resetRestore",
"SessionStore:flush",
"SessionStore:becomeActiveProcess",
"SessionStore:prepareForProcessChange",
"SessionStore:setRestoringDocument",
];
class ContentSessionStore {
@@ -522,18 +528,13 @@ class ContentSessionStore {
this.contentRestoreInitialized = false;
this.waitRestoreSHistoryInParent = false;
this.restoreTabContentData = null;
XPCOMUtils.defineLazyGetter(this, "contentRestore", () => {
this.contentRestoreInitialized = true;
return new ContentRestore(mm);
});
this.handlers = [new EventListener(this), this.messageQueue];
this._shistoryInParent = Services.appinfo.sessionHistoryInParent;
if (this._shistoryInParent) {
if (Services.appinfo.sessionHistoryInParent) {
this.mm.sendAsyncMessage("SessionStore:addSHistoryListener");
} else {
this.handlers.push(new SessionHistoryListener(this));
@@ -566,45 +567,11 @@ class ContentSessionStore {
case "SessionStore:restoreHistory":
this.restoreHistory(data);
break;
case "SessionStore:finishRestoreHistory":
this.finishRestoreHistory();
break;
case "SessionStore:OnHistoryNewEntry":
this.contentRestore.restoreOnNewEntry(data.uri);
break;
case "SessionStore:OnHistoryReload":
// On reload, restore tab contents.
this.contentRestore.restoreTabContent(
null,
false,
() => {
// Tell SessionStore.jsm that it may want to restore some more tabs,
// since it restores a max of MAX_CONCURRENT_TAB_RESTORES at a time.
this.mm.sendAsyncMessage("SessionStore:restoreTabContentComplete", {
epoch: this.epoch,
});
},
() => {
// Tell SessionStore.jsm to remove restoreListener.
this.mm.sendAsyncMessage("SessionStore:removeRestoreListener", {
epoch: this.epoch,
});
},
() => {
// Tell SessionStore.jsm to reload currentEntry.
this.mm.sendAsyncMessage("SessionStore:reloadCurrentEntry", {
epoch: this.epoch,
});
}
);
case "SessionStore:restoreDocShellState":
this.restoreDocShellState(data);
break;
case "SessionStore:restoreTabContent":
if (this.waitRestoreSHistoryInParent) {
// Queue the TabContentData if we haven't finished sHistoryRestore yet.
this.restoreTabContentData = data;
} else {
this.restoreTabContent(data);
}
this.restoreTabContent(data);
break;
case "SessionStore:resetRestore":
this.contentRestore.resetRestore();
@@ -613,7 +580,7 @@ class ContentSessionStore {
this.flush(data);
break;
case "SessionStore:becomeActiveProcess":
if (!this._shistoryInParent) {
if (!Services.appinfo.sessionHistoryInParent) {
SessionHistoryListener.collect();
}
break;
@@ -626,62 +593,40 @@ class ContentSessionStore {
// parent process.
this.mm.docShell.persistLayoutHistoryState();
break;
case "SessionStore:setRestoringDocument":
this.contentRestore.setRestoringDocument(data);
break;
default:
debug("received unknown message '" + name + "'");
break;
}
}
restoreHistory({ epoch, tabData, loadArguments, isRemotenessUpdate }) {
this.contentRestore.restoreHistory(
tabData,
loadArguments,
{
// Note: The callbacks passed here will only be used when a load starts
// that was not initiated by sessionstore itself. This can happen when
// some code calls browser.loadURI() or browser.reload() on a pending
// browser/tab.
// non-SHIP only
restoreHistory(data) {
let { epoch, tabData, loadArguments, isRemotenessUpdate } = data;
onLoadStarted: () => {
// Notify the parent that the tab is no longer pending.
this.mm.sendAsyncMessage("SessionStore:restoreTabContentStarted", {
epoch,
});
},
this.contentRestore.restoreHistory(tabData, loadArguments, {
// Note: The callbacks passed here will only be used when a load starts
// that was not initiated by sessionstore itself. This can happen when
// some code calls browser.loadURI() or browser.reload() on a pending
// browser/tab.
onLoadFinished: () => {
// Tell SessionStore.jsm that it may want to restore some more tabs,
// since it restores a max of MAX_CONCURRENT_TAB_RESTORES at a time.
this.mm.sendAsyncMessage("SessionStore:restoreTabContentComplete", {
epoch,
});
},
removeRestoreListener: () => {
if (!this._shistoryInParent) {
return;
}
// Notify the parent that the tab is no longer pending.
this.mm.sendAsyncMessage("SessionStore:removeRestoreListener", {
epoch,
});
},
requestRestoreSHistory: () => {
if (!this._shistoryInParent) {
return;
}
this.waitRestoreSHistoryInParent = true;
// Send tabData to the parent process.
this.mm.sendAsyncMessage("SessionStore:restoreSHistoryInParent", {
epoch,
});
},
onLoadStarted: () => {
// Notify the parent that the tab is no longer pending.
this.mm.sendAsyncMessage("SessionStore:restoreTabContentStarted", {
epoch,
});
},
this._shistoryInParent
);
onLoadFinished: () => {
// Tell SessionStore.jsm that it may want to restore some more tabs,
// since it restores a max of MAX_CONCURRENT_TAB_RESTORES at a time.
this.mm.sendAsyncMessage("SessionStore:restoreTabContentComplete", {
epoch,
});
},
});
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_DEFAULT) {
// For non-remote tabs, when restoreHistory finishes, we send a synchronous
@@ -698,7 +643,7 @@ class ContentSessionStore {
epoch,
isRemotenessUpdate,
});
} else if (!this._shistoryInParent) {
} else {
this.mm.sendAsyncMessage("SessionStore:restoreHistoryComplete", {
epoch,
isRemotenessUpdate,
@@ -706,50 +651,35 @@ class ContentSessionStore {
}
}
finishRestoreHistory() {
this.contentRestore.finishRestoreHistory({
// Note: The callbacks passed here will only be used when a load starts
// that was not initiated by sessionstore itself. This can happen when
// some code calls browser.loadURI() or browser.reload() on a pending
// browser/tab.
onLoadStarted: () => {
// Notify the parent that the tab is no longer pending.
this.mm.sendAsyncMessage("SessionStore:restoreTabContentStarted", {
epoch: this.epoch,
});
},
// SHIP only
restoreDocShellState(data) {
let { epoch, tabData } = data;
onLoadFinished: () => {
// Tell SessionStore.jsm that it may want to restore some more tabs,
// since it restores a max of MAX_CONCURRENT_TAB_RESTORES at a time.
this.mm.sendAsyncMessage("SessionStore:restoreTabContentComplete", {
epoch: this.epoch,
});
},
removeRestoreListener: () => {
if (!this._shistoryInParent) {
return;
}
// Notify the parent that the tab is no longer pending.
this.mm.sendAsyncMessage("SessionStore:removeRestoreListener", {
epoch: this.epoch,
});
},
});
this.mm.sendAsyncMessage("SessionStore:restoreHistoryComplete", {
epoch: this.epoch,
});
if (this.restoreTabContentData) {
this.restoreTabContent(this.restoreTabContentData);
this.restoreTabContentData = null;
if (!Services.appinfo.sessionHistoryInParent) {
throw new Error("This function should only be used with SHIP");
}
this.waitRestoreSHistoryInParent = false;
let { docShell } = this.mm;
if (tabData.uri) {
docShell.setCurrentURI(Services.io.newURI(tabData.uri));
}
if (tabData.disallow) {
SessionStoreUtils.restoreDocShellCapabilities(docShell, tabData.disallow);
}
if (tabData.storage) {
SessionStoreUtils.restoreSessionStorage(docShell, tabData.storage);
}
// Since we don't send restoreHistory, we need to tell the parent when
// to call SSTabRestoring (via restoreHistoryComplete)
this.mm.sendAsyncMessage("SessionStore:restoreHistoryComplete", { epoch });
}
restoreTabContent({ loadArguments, isRemotenessUpdate, reason }) {
if (Services.appinfo.sessionHistoryInParent) {
throw new Error("This function should be unused with SHIP");
}
let epoch = this.epoch;
// We need to pass the value of didStartLoad back to SessionStore.jsm.
@@ -763,17 +693,6 @@ class ContentSessionStore {
epoch,
isRemotenessUpdate,
});
},
() => {
// Tell SessionStore.jsm to remove restore listener.
this.mm.sendAsyncMessage("SessionStore:removeRestoreListener", {
epoch,
});
},
() => {
this.mm.sendAsyncMessage("SessionStore:reloadCurrentEntry", {
epoch,
});
}
);