browser/components/migration/src/FirefoxProfileMigrator.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/browser/components/migration/src/FirefoxProfileMigrator.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,134 @@
     1.4 +/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 + * vim: sw=2 ts=2 sts=2 et */
     1.6 + /* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +"use strict";
    1.11 +
    1.12 +/*
    1.13 + * Migrates from a Firefox profile in a lossy manner in order to clean up a
    1.14 + * user's profile.  Data is only migrated where the benefits outweigh the
    1.15 + * potential problems caused by importing undesired/invalid configurations
    1.16 + * from the source profile.
    1.17 + */
    1.18 +
    1.19 +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
    1.20 +Components.utils.import("resource:///modules/MigrationUtils.jsm");
    1.21 +Components.utils.import("resource://gre/modules/Services.jsm");
    1.22 +XPCOMUtils.defineLazyModuleGetter(this, "PlacesBackups",
    1.23 +                                  "resource://gre/modules/PlacesBackups.jsm");
    1.24 +XPCOMUtils.defineLazyModuleGetter(this, "SessionMigration",
    1.25 +                                  "resource:///modules/sessionstore/SessionMigration.jsm");
    1.26 +
    1.27 +function FirefoxProfileMigrator() { }
    1.28 +
    1.29 +FirefoxProfileMigrator.prototype = Object.create(MigratorPrototype);
    1.30 +
    1.31 +FirefoxProfileMigrator.prototype._getFileObject = function(dir, fileName) {
    1.32 +  let file = dir.clone();
    1.33 +  file.append(fileName);
    1.34 +
    1.35 +  // File resources are monolithic.  We don't make partial copies since
    1.36 +  // they are not expected to work alone. Return null to avoid trying to
    1.37 +  // copy non-existing files.
    1.38 +  return file.exists() ? file : null;
    1.39 +}
    1.40 +
    1.41 +FirefoxProfileMigrator.prototype.getResources = function() {
    1.42 +  // Only allow migrating from the default (selected) profile since this will
    1.43 +  // be the only one returned by the toolkit profile service after bug 214675.
    1.44 +  let sourceProfile =
    1.45 +    Components.classes["@mozilla.org/toolkit/profile-service;1"]
    1.46 +              .getService(Components.interfaces.nsIToolkitProfileService)
    1.47 +              .selectedProfile;
    1.48 +  if (!sourceProfile)
    1.49 +    return null;
    1.50 +
    1.51 +  let sourceProfileDir = sourceProfile.rootDir;
    1.52 +  if (!sourceProfileDir || !sourceProfileDir.exists() ||
    1.53 +      !sourceProfileDir.isReadable())
    1.54 +    return null;
    1.55 +
    1.56 +  // Being a startup-only migrator, we can rely on
    1.57 +  // MigrationUtils.profileStartup being set.
    1.58 +  let currentProfileDir = MigrationUtils.profileStartup.directory;
    1.59 +
    1.60 +  // Surely data cannot be imported from the current profile.
    1.61 +  if (sourceProfileDir.equals(currentProfileDir))
    1.62 +    return null;
    1.63 +
    1.64 +  let getFileResource = function(aMigrationType, aFileNames) {
    1.65 +    let files = [];
    1.66 +    for (let fileName of aFileNames) {
    1.67 +      let file = this._getFileObject(sourceProfileDir, fileName);
    1.68 +      if (!file)
    1.69 +        return null;
    1.70 +      files.push(file);
    1.71 +    }
    1.72 +    return {
    1.73 +      type: aMigrationType,
    1.74 +      migrate: function(aCallback) {
    1.75 +        for (let file of files) {
    1.76 +          file.copyTo(currentProfileDir, "");
    1.77 +        }
    1.78 +        aCallback(true);
    1.79 +      }
    1.80 +    };
    1.81 +  }.bind(this);
    1.82 +
    1.83 +  let types = MigrationUtils.resourceTypes;
    1.84 +  let places = getFileResource(types.HISTORY, ["places.sqlite"]);
    1.85 +  let cookies = getFileResource(types.COOKIES, ["cookies.sqlite"]);
    1.86 +  let passwords = getFileResource(types.PASSWORDS,
    1.87 +                                  ["signons.sqlite", "key3.db"]);
    1.88 +  let formData = getFileResource(types.FORMDATA, ["formhistory.sqlite"]);
    1.89 +  let bookmarksBackups = getFileResource(types.OTHERDATA,
    1.90 +    [PlacesBackups.profileRelativeFolderPath]);
    1.91 +  let dictionary = getFileResource(types.OTHERDATA, ["persdict.dat"]);
    1.92 +
    1.93 +  let sessionFile = this._getFileObject(sourceProfileDir, "sessionstore.js");
    1.94 +  let session;
    1.95 +  if (sessionFile) {
    1.96 +    session = {
    1.97 +      type: types.SESSION,
    1.98 +      migrate: function(aCallback) {
    1.99 +        let newSessionFile = currentProfileDir.clone();
   1.100 +        newSessionFile.append("sessionstore.js");
   1.101 +        let migrationPromise = SessionMigration.migrate(sessionFile.path, newSessionFile.path);
   1.102 +        migrationPromise.then(function() {
   1.103 +          let buildID = Services.appinfo.platformBuildID;
   1.104 +          let mstone = Services.appinfo.platformVersion;
   1.105 +          // Force the browser to one-off resume the session that we give it:
   1.106 +          Services.prefs.setBoolPref("browser.sessionstore.resume_session_once", true);
   1.107 +          // Reset the homepage_override prefs so that the browser doesn't override our
   1.108 +          // session with the "what's new" page:
   1.109 +          Services.prefs.setCharPref("browser.startup.homepage_override.mstone", mstone);
   1.110 +          Services.prefs.setCharPref("browser.startup.homepage_override.buildID", buildID);
   1.111 +          // It's too early in startup for the pref service to have a profile directory,
   1.112 +          // so we have to manually tell it where to save the prefs file.
   1.113 +          let newPrefsFile = currentProfileDir.clone();
   1.114 +          newPrefsFile.append("prefs.js");
   1.115 +          Services.prefs.savePrefFile(newPrefsFile);
   1.116 +          aCallback(true);
   1.117 +        }, function() {
   1.118 +          aCallback(false);
   1.119 +        });
   1.120 +      }
   1.121 +    }
   1.122 +  }
   1.123 +
   1.124 +  return [r for each (r in [places, cookies, passwords, formData,
   1.125 +                            dictionary, bookmarksBackups, session]) if (r)];
   1.126 +}
   1.127 +
   1.128 +Object.defineProperty(FirefoxProfileMigrator.prototype, "startupOnlyMigrator", {
   1.129 +  get: function() true
   1.130 +});
   1.131 +
   1.132 +
   1.133 +FirefoxProfileMigrator.prototype.classDescription = "Firefox Profile Migrator";
   1.134 +FirefoxProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=firefox";
   1.135 +FirefoxProfileMigrator.prototype.classID = Components.ID("{91185366-ba97-4438-acba-48deaca63386}");
   1.136 +
   1.137 +this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FirefoxProfileMigrator]);

mercurial