michael@0: /* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * vim: sw=2 ts=2 sts=2 et */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: /* michael@0: * Migrates from a Firefox profile in a lossy manner in order to clean up a michael@0: * user's profile. Data is only migrated where the benefits outweigh the michael@0: * potential problems caused by importing undesired/invalid configurations michael@0: * from the source profile. michael@0: */ michael@0: michael@0: Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: Components.utils.import("resource:///modules/MigrationUtils.jsm"); michael@0: Components.utils.import("resource://gre/modules/Services.jsm"); michael@0: XPCOMUtils.defineLazyModuleGetter(this, "PlacesBackups", michael@0: "resource://gre/modules/PlacesBackups.jsm"); michael@0: XPCOMUtils.defineLazyModuleGetter(this, "SessionMigration", michael@0: "resource:///modules/sessionstore/SessionMigration.jsm"); michael@0: michael@0: function FirefoxProfileMigrator() { } michael@0: michael@0: FirefoxProfileMigrator.prototype = Object.create(MigratorPrototype); michael@0: michael@0: FirefoxProfileMigrator.prototype._getFileObject = function(dir, fileName) { michael@0: let file = dir.clone(); michael@0: file.append(fileName); michael@0: michael@0: // File resources are monolithic. We don't make partial copies since michael@0: // they are not expected to work alone. Return null to avoid trying to michael@0: // copy non-existing files. michael@0: return file.exists() ? file : null; michael@0: } michael@0: michael@0: FirefoxProfileMigrator.prototype.getResources = function() { michael@0: // Only allow migrating from the default (selected) profile since this will michael@0: // be the only one returned by the toolkit profile service after bug 214675. michael@0: let sourceProfile = michael@0: Components.classes["@mozilla.org/toolkit/profile-service;1"] michael@0: .getService(Components.interfaces.nsIToolkitProfileService) michael@0: .selectedProfile; michael@0: if (!sourceProfile) michael@0: return null; michael@0: michael@0: let sourceProfileDir = sourceProfile.rootDir; michael@0: if (!sourceProfileDir || !sourceProfileDir.exists() || michael@0: !sourceProfileDir.isReadable()) michael@0: return null; michael@0: michael@0: // Being a startup-only migrator, we can rely on michael@0: // MigrationUtils.profileStartup being set. michael@0: let currentProfileDir = MigrationUtils.profileStartup.directory; michael@0: michael@0: // Surely data cannot be imported from the current profile. michael@0: if (sourceProfileDir.equals(currentProfileDir)) michael@0: return null; michael@0: michael@0: let getFileResource = function(aMigrationType, aFileNames) { michael@0: let files = []; michael@0: for (let fileName of aFileNames) { michael@0: let file = this._getFileObject(sourceProfileDir, fileName); michael@0: if (!file) michael@0: return null; michael@0: files.push(file); michael@0: } michael@0: return { michael@0: type: aMigrationType, michael@0: migrate: function(aCallback) { michael@0: for (let file of files) { michael@0: file.copyTo(currentProfileDir, ""); michael@0: } michael@0: aCallback(true); michael@0: } michael@0: }; michael@0: }.bind(this); michael@0: michael@0: let types = MigrationUtils.resourceTypes; michael@0: let places = getFileResource(types.HISTORY, ["places.sqlite"]); michael@0: let cookies = getFileResource(types.COOKIES, ["cookies.sqlite"]); michael@0: let passwords = getFileResource(types.PASSWORDS, michael@0: ["signons.sqlite", "key3.db"]); michael@0: let formData = getFileResource(types.FORMDATA, ["formhistory.sqlite"]); michael@0: let bookmarksBackups = getFileResource(types.OTHERDATA, michael@0: [PlacesBackups.profileRelativeFolderPath]); michael@0: let dictionary = getFileResource(types.OTHERDATA, ["persdict.dat"]); michael@0: michael@0: let sessionFile = this._getFileObject(sourceProfileDir, "sessionstore.js"); michael@0: let session; michael@0: if (sessionFile) { michael@0: session = { michael@0: type: types.SESSION, michael@0: migrate: function(aCallback) { michael@0: let newSessionFile = currentProfileDir.clone(); michael@0: newSessionFile.append("sessionstore.js"); michael@0: let migrationPromise = SessionMigration.migrate(sessionFile.path, newSessionFile.path); michael@0: migrationPromise.then(function() { michael@0: let buildID = Services.appinfo.platformBuildID; michael@0: let mstone = Services.appinfo.platformVersion; michael@0: // Force the browser to one-off resume the session that we give it: michael@0: Services.prefs.setBoolPref("browser.sessionstore.resume_session_once", true); michael@0: // Reset the homepage_override prefs so that the browser doesn't override our michael@0: // session with the "what's new" page: michael@0: Services.prefs.setCharPref("browser.startup.homepage_override.mstone", mstone); michael@0: Services.prefs.setCharPref("browser.startup.homepage_override.buildID", buildID); michael@0: // It's too early in startup for the pref service to have a profile directory, michael@0: // so we have to manually tell it where to save the prefs file. michael@0: let newPrefsFile = currentProfileDir.clone(); michael@0: newPrefsFile.append("prefs.js"); michael@0: Services.prefs.savePrefFile(newPrefsFile); michael@0: aCallback(true); michael@0: }, function() { michael@0: aCallback(false); michael@0: }); michael@0: } michael@0: } michael@0: } michael@0: michael@0: return [r for each (r in [places, cookies, passwords, formData, michael@0: dictionary, bookmarksBackups, session]) if (r)]; michael@0: } michael@0: michael@0: Object.defineProperty(FirefoxProfileMigrator.prototype, "startupOnlyMigrator", { michael@0: get: function() true michael@0: }); michael@0: michael@0: michael@0: FirefoxProfileMigrator.prototype.classDescription = "Firefox Profile Migrator"; michael@0: FirefoxProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=firefox"; michael@0: FirefoxProfileMigrator.prototype.classID = Components.ID("{91185366-ba97-4438-acba-48deaca63386}"); michael@0: michael@0: this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FirefoxProfileMigrator]);