Bug 1287091 - part 1 - ContextualIdentityService should use a storage for the containers, r=Gijs

This commit is contained in:
Andrea Marchesini 2016-07-23 08:57:40 +02:00
parent b0efbe0ef8
commit 6871885a3e
4 changed files with 118 additions and 10 deletions

View File

@ -8,6 +8,7 @@ var Cu = Components.utils;
var Cc = Components.classes;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/ContextualIdentityService.jsm");
Cu.import("resource://gre/modules/NotificationDB.jsm");
Cu.import("resource:///modules/RecentWindow.jsm");
@ -56,8 +57,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "WindowsUIUtils",
"@mozilla.org/windows-ui-utils;1", "nsIWindowsUIUtils");
XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager",
"resource://gre/modules/LightweightThemeManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ContextualIdentityService",
"resource://gre/modules/ContextualIdentityService.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "gAboutNewTabService",
"@mozilla.org/browser/aboutnewtab-service;1",
"nsIAboutNewTabService");

View File

@ -4,6 +4,7 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
Components.utils.import("resource://gre/modules/ContextualIdentityService.jsm");
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
Components.utils.import("resource://gre/modules/InlineSpellChecker.jsm");
Components.utils.import("resource://gre/modules/LoginManagerContextMenu.jsm");
@ -11,8 +12,6 @@ Components.utils.import("resource://gre/modules/BrowserUtils.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ContextualIdentityService",
"resource://gre/modules/ContextualIdentityService.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper",
"resource://gre/modules/LoginHelper.jsm");

View File

@ -5,6 +5,7 @@
// Services = object with smart getters for common XPCOM services
Components.utils.import("resource://gre/modules/AppConstants.jsm");
Components.utils.import("resource://gre/modules/ContextualIdentityService.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
@ -13,9 +14,6 @@ Components.utils.import("resource:///modules/RecentWindow.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ShellService",
"resource:///modules/ShellService.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ContextualIdentityService",
"resource://gre/modules/ContextualIdentityService.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
"@mozilla.org/browser/aboutnewtab-service;1",
"nsIAboutNewTabService");

View File

@ -7,16 +7,34 @@ this.EXPORTED_SYMBOLS = ["ContextualIdentityService"];
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm")
Cu.import("resource://gre/modules/Services.jsm");
const DEFAULT_TAB_COLOR = "#909090"
const DEFAULT_TAB_COLOR = "#909090";
const SAVE_DELAY_MS = 1500;
XPCOMUtils.defineLazyGetter(this, "gBrowserBundle", function() {
return Services.strings.createBundle("chrome://browser/locale/browser.properties");
});
XPCOMUtils.defineLazyGetter(this, "gTextDecoder", function () {
return new TextDecoder();
});
XPCOMUtils.defineLazyGetter(this, "gTextEncoder", function () {
return new TextEncoder();
});
XPCOMUtils.defineLazyModuleGetter(this, "AsyncShutdown",
"resource://gre/modules/AsyncShutdown.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "DeferredTask",
"resource://gre/modules/DeferredTask.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
this.ContextualIdentityService = {
_identities: [
_defaultIdentities: [
{ userContextId: 1,
public: true,
icon: "chrome://browser/skin/usercontext/personal.svg",
@ -62,15 +80,107 @@ this.ContextualIdentityService = {
alreadyOpened: false },
],
_identities: null,
_path: null,
_dataReady: false,
_saver: null,
init() {
this._path = OS.Path.join(OS.Constants.Path.profileDir, "containers.json");
this._saver = new DeferredTask(() => this.save(), SAVE_DELAY_MS);
AsyncShutdown.profileBeforeChange.addBlocker("ContextualIdentityService: writing data",
() => this._saver.finalize());
this.load();
},
load() {
OS.File.read(this._path).then(bytes => {
// If synchronous loading happened in the meantime, exit now.
if (this._dataReady) {
return;
}
try {
this._identities = JSON.parse(gTextDecoder.decode(bytes));
this._dataReady = true;
} catch(error) {
this.loadError(error);
}
}, (error) => {
this.loadError(error);
});
},
loadError(error) {
if (!(error instanceof OS.File.Error && error.becauseNoSuchFile) &&
!(error instanceof Components.Exception &&
error.result == Cr.NS_ERROR_FILE_NOT_FOUND)) {
// Let's report the error.
Cu.reportError(error);
}
// If synchronous loading happened in the meantime, exit now.
if (this._dataReady) {
return;
}
this._identities = this._defaultIdentities;
this._dataReady = true;
this.saveSoon();
},
saveSoon() {
this._saver.arm();
},
save() {
let bytes = gTextEncoder.encode(JSON.stringify(this._identities));
return OS.File.writeAtomic(this._path, bytes,
{ tmpPath: this._path + ".tmp" });
},
ensureDataReady() {
if (this._dataReady) {
return;
}
try {
// This reads the file and automatically detects the UTF-8 encoding.
let inputStream = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
inputStream.init(new FileUtils.File(this._path),
FileUtils.MODE_RDONLY, FileUtils.PERMS_FILE, 0);
try {
let json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
this._identities = json.decodeFromStream(inputStream,
inputStream.available());
this._dataReady = true;
} finally {
inputStream.close();
}
} catch (error) {
this.loadError(error);
return;
}
},
getIdentities() {
this.ensureDataReady();
return this._identities.filter(info => info.public);
},
getPrivateIdentity(label) {
this.ensureDataReady();
return this._identities.find(info => !info.public && info.label == label);
},
getIdentityFromId(userContextId) {
this.ensureDataReady();
return this._identities.find(info => info.userContextId == userContextId);
},
@ -122,3 +232,5 @@ this.ContextualIdentityService = {
}
},
}
ContextualIdentityService.init();