Bug 1368815 - ContextualIdentityService should remove containers only when all the tabs are completely closed, r=mconley

This commit is contained in:
Andrea Marchesini 2017-07-25 13:26:28 +02:00
Родитель 7e5724db61
Коммит aa6c45ef01
6 изменённых файлов: 61 добавлений и 12 удалений

Просмотреть файл

@ -35,12 +35,12 @@ add_task(async function test() {
is(ContextualIdentityService.countContainerTabs(1), 2, "2 container tabs created with id 1");
is(ContextualIdentityService.countContainerTabs(2), 1, "1 container tab created with id 2");
ContextualIdentityService.closeContainerTabs(1);
await ContextualIdentityService.closeContainerTabs(1);
is(ContextualIdentityService.countContainerTabs(), 1, "1 container tab created");
is(ContextualIdentityService.countContainerTabs(1), 0, "0 container tabs created with id 1");
is(ContextualIdentityService.countContainerTabs(2), 1, "1 container tab created with id 2");
ContextualIdentityService.closeContainerTabs();
await ContextualIdentityService.closeContainerTabs();
is(ContextualIdentityService.countContainerTabs(), 0, "0 container tabs at the end.");
is(ContextualIdentityService.countContainerTabs(1), 0, "0 container tabs at the end with id 1.");
is(ContextualIdentityService.countContainerTabs(2), 0, "0 container tabs at the end with id 2.");

Просмотреть файл

@ -40,7 +40,7 @@ let gContainersPane = {
}
},
onRemoveClick(button) {
async onRemoveClick(button) {
let userContextId = parseInt(button.getAttribute("value"), 10);
let count = ContextualIdentityService.countContainerTabs(userContextId);
@ -62,7 +62,7 @@ let gContainersPane = {
return;
}
ContextualIdentityService.closeContainerTabs(userContextId);
await ContextualIdentityService.closeContainerTabs(userContextId);
}
ContextualIdentityService.remove(userContextId);

Просмотреть файл

@ -7,8 +7,6 @@
Components.utils.import("resource://gre/modules/AppConstants.jsm");
Components.utils.import("resource://gre/modules/PluralForm.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ContextualIdentityService",
"resource://gre/modules/ContextualIdentityService.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper",

Просмотреть файл

@ -40,7 +40,7 @@ let gContainersPane = {
}
},
onRemoveClick(button) {
async onRemoveClick(button) {
let userContextId = parseInt(button.getAttribute("value"), 10);
let count = ContextualIdentityService.countContainerTabs(userContextId);
@ -62,7 +62,7 @@ let gContainersPane = {
return;
}
ContextualIdentityService.closeContainerTabs(userContextId);
await ContextualIdentityService.closeContainerTabs(userContextId);
}
ContextualIdentityService.remove(userContextId);

Просмотреть файл

@ -87,6 +87,7 @@ var gPrivacyPane = {
let count = ContextualIdentityService.countContainerTabs();
if (count == 0) {
ContextualIdentityService.notifyAllContainersCleared();
Services.prefs.setBoolPref("privacy.userContext.enabled", false);
return;
}
@ -106,8 +107,10 @@ var gPrivacyPane = {
let rv = Services.prompt.confirmEx(window, title, message, buttonFlags,
okButton, cancelButton, null, null, {});
if (rv == 0) {
ContextualIdentityService.closeContainerTabs();
Services.prefs.setBoolPref("privacy.userContext.enabled", false);
ContextualIdentityService.closeContainerTabs().then(() => {
ContextualIdentityService.notifyAllContainersCleared();
});
return;
}

Просмотреть файл

@ -33,6 +33,30 @@ XPCOMUtils.defineLazyModuleGetter(this, "DeferredTask",
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
function _TabRemovalObserver(resolver, tabParentIds) {
this._resolver = resolver;
this._tabParentIds = tabParentIds;
Services.obs.addObserver(this, "ipc:browser-destroyed");
}
_TabRemovalObserver.prototype = {
_resolver: null,
_tabParentIds: null,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
observe(subject, topic, data) {
let tabParent = subject.QueryInterface(Ci.nsITabParent);
if (this._tabParentIds.has(tabParent.tabId)) {
this._tabParentIds.delete(tabParent.tabId);
if (this._tabParentIds.size == 0) {
Services.obs.removeObserver(this, "ipc:browser-destroyed");
this._resolver();
}
}
}
};
function _ContextualIdentityService(path) {
this.init(path);
}
@ -309,9 +333,33 @@ _ContextualIdentityService.prototype = {
},
closeContainerTabs(userContextId = 0) {
this._forEachContainerTab(function(tab, tabbrowser) {
tabbrowser.removeTab(tab);
}, userContextId);
return new Promise(resolve => {
let tabParentIds = new Set();
this._forEachContainerTab((tab, tabbrowser) => {
let frameLoader = tab.linkedBrowser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
// We don't have tabParent in non-e10s mode.
if (frameLoader.tabParent) {
tabParentIds.add(frameLoader.tabParent.tabId);
}
tabbrowser.removeTab(tab);
}, userContextId);
if (tabParentIds.size == 0) {
resolve();
return;
}
new _TabRemovalObserver(resolve, tabParentIds);
});
},
notifyAllContainersCleared() {
for (let identity of this._identities) {
Services.obs.notifyObservers(null, "clear-origin-attributes-data",
JSON.stringify({ userContextId: identity.userContextId }));
}
},
_forEachContainerTab(callback, userContextId = 0) {