Bug 715099 - Convert nsProfileMigrator to JS so we can JS modules on migration. r=mak.

This commit is contained in:
Asaf Romano 2012-01-16 09:27:34 +02:00
parent 77dae2f2ab
commit f5415954e4
7 changed files with 152 additions and 329 deletions

View File

@ -49,7 +49,6 @@
#include "nsGNOMEShellService.h"
#endif
#include "nsProfileMigrator.h"
#if defined(XP_WIN) && !defined(__MINGW32__)
#include "nsIEProfileMigrator.h"
#elif defined(XP_MACOSX)
@ -77,7 +76,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacShellService)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init)
#endif
NS_GENERIC_FACTORY_CONSTRUCTOR(nsProfileMigrator)
#if defined(XP_WIN) && !defined(__MINGW32__)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIEProfileMigrator)
#elif defined(XP_MACOSX)
@ -96,7 +94,6 @@ NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
#endif
NS_DEFINE_NAMED_CID(NS_FEEDSNIFFER_CID);
NS_DEFINE_NAMED_CID(NS_BROWSER_ABOUT_REDIRECTOR_CID);
NS_DEFINE_NAMED_CID(NS_FIREFOX_PROFILEMIGRATOR_CID);
#if defined(XP_WIN) && !defined(__MINGW32__)
NS_DEFINE_NAMED_CID(NS_WINIEPROFILEMIGRATOR_CID);
#elif defined(XP_MACOSX)
@ -114,7 +111,6 @@ static const mozilla::Module::CIDEntry kBrowserCIDs[] = {
#endif
{ &kNS_FEEDSNIFFER_CID, false, NULL, nsFeedSnifferConstructor },
{ &kNS_BROWSER_ABOUT_REDIRECTOR_CID, false, NULL, AboutRedirector::Create },
{ &kNS_FIREFOX_PROFILEMIGRATOR_CID, false, NULL, nsProfileMigratorConstructor },
#if defined(XP_WIN) && !defined(__MINGW32__)
{ &kNS_WINIEPROFILEMIGRATOR_CID, false, NULL, nsIEProfileMigratorConstructor },
#elif defined(XP_MACOSX)
@ -148,7 +144,6 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
#endif
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "home", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "permissions", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_PROFILEMIGRATOR_CONTRACTID, &kNS_FIREFOX_PROFILEMIGRATOR_CID },
#if defined(XP_WIN) && !defined(__MINGW32__)
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "ie", &kNS_WINIEPROFILEMIGRATOR_CID },
#elif defined(XP_MACOSX)

View File

@ -1,4 +1,6 @@
component {4cec1de4-1671-4fc3-a53e-6c539dc77a26} ChromeProfileMigrator.js
contract @mozilla.org/profile/migrator;1?app=browser&type=chrome {4cec1de4-1671-4fc3-a53e-6c539dc77a26}
component {91185366-ba97-4438-acba-48deaca63386} FirefoxProfileMigrator.js
contract @mozilla.org/profile/migrator;1?app=browser&type=firefox {91185366-ba97-4438-acba-48deaca63386}
component {6F8BB968-C14F-4D6F-9733-6C6737B35DCE} ProfileMigrator.js
contract @mozilla.org/toolkit/profile-migrator;1 {6F8BB968-C14F-4D6F-9733-6C6737B35DCE}
component {4cec1de4-1671-4fc3-a53e-6c539dc77a26} ChromeProfileMigrator.js
contract @mozilla.org/profile/migrator;1?app=browser&type=chrome {4cec1de4-1671-4fc3-a53e-6c539dc77a26}
component {91185366-ba97-4438-acba-48deaca63386} FirefoxProfileMigrator.js
contract @mozilla.org/profile/migrator;1?app=browser&type=firefox {91185366-ba97-4438-acba-48deaca63386}

View File

@ -49,8 +49,7 @@ USE_STATIC_LIBS = 1
endif
CPPSRCS = nsProfileMigrator.cpp \
nsBrowserProfileMigratorUtils.cpp \
CPPSRCS = nsBrowserProfileMigratorUtils.cpp \
$(NULL)
ifeq ($(OS_ARCH)_$(GNU_CXX),WINNT_)
@ -64,6 +63,7 @@ CPPSRCS += nsSafariProfileMigrator.cpp \
endif
EXTRA_PP_COMPONENTS = \
ProfileMigrator.js \
ChromeProfileMigrator.js \
FirefoxProfileMigrator.js \
$(NULL)

View File

@ -0,0 +1,141 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
"use strict";
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
function ProfileMigrator() {
}
ProfileMigrator.prototype = {
migrate: function PM_migrate(aStartup) {
// By opening the wizard with a supplied migrator, it will automatically
// migrate from it.
let [key, migrator] = this._getDefaultMigrator();
if (!key)
return;
let params = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
params.appendElement(this._toCString(key), false);
params.appendElement(migrator, false);
params.appendElement(aStartup, false);
Services.ww.openWindow(null,
"chrome://browser/content/migration/migration.xul",
"_blank",
"chrome,dialog,modal,centerscreen,titlebar",
params);
},
_toCString: function PM__toCString(aStr) {
let cstr = Cc["@mozilla.org/supports-cstring;1"].
createInstance(Ci.nsISupportsCString);
cstr.data = aStr;
return cstr;
},
_getMigratorIfSourceExists: function PM__getMigratorIfSourceExists(aKey) {
let cid = "@mozilla.org/profile/migrator;1?app=browser&type=" + aKey;
let migrator = Cc[cid].createInstance(Ci.nsIBrowserProfileMigrator);
if (migrator.sourceExists)
return migrator;
return null;
},
// We don't yet support checking for the default browser on all platforms,
// needless to say we don't have migrators for all browsers. Thus, for each
// platform, there's a fallback list of migrators used in these cases.
_PLATFORM_FALLBACK_LIST:
#ifdef XP_WIN
["ie", "chrome", /* safari */],
#elifdef XP_MACOSX
["safari", "chrome"],
#else
["chrome"],
#endif
_getDefaultMigrator: function PM__getDefaultMigrator() {
let migratorsOrdered = Array.slice(this._PLATFORM_FALLBACK_LIST);
let defaultBrowser = "";
#ifdef XP_WIN
try {
const REG_KEY = "SOFTWARE\\Classes\\HTTP\\shell\\open\\command";
let regKey = Cc["@mozilla.org/windows-registry-key;1"].
createInstance(Ci.nsIWindowsRegKey);
regKey.open(regKey.ROOT_KEY_LOCAL_MACHINE, REG_KEY,
regKey.ACCESS_READ);
let value = regKey.readStringValue("").toLowerCase();
let pathMatches = value.match(/^"?(.+?\.exe)"?/);
if (!pathMatches) {
throw new Error("Could not extract path from " +
REG_KEY + "(" + value + ")");
}
// We want to find out what the default browser is but the path in and of
// itself isn't enough. Why? Because sometimes on Windows paths get
// truncated like so: C:\PROGRA~1\MOZILL~2\MOZILL~1.EXE. How do we know
// what product that is? Mozilla's file objects do nothing to 'normalize'
// the path so we need to attain an actual product descriptor from the
// file somehow, and in this case it means getting the "InternalName"
// field of the file's VERSIONINFO resource.
//
// In the file's resource segment there is a VERSIONINFO section that is
// laid out like this:
//
// VERSIONINFO
// StringFileInfo
// <TranslationID>
// InternalName "iexplore"
// VarFileInfo
// Translation <TranslationID>
//
// By Querying the VERSIONINFO section for its Tranlations, we can find
// out where the InternalName lives (A file can have more than one
// translation of its VERSIONINFO segment, but we just assume the first
// one).
let file = FileUtils.File(pathMatches[1])
.QueryInterface(Ci.nsILocalFileWin);
switch (file.getVersionInfoField("InternalName").toLowerCase()) {
case "iexplore":
defaultBrowser = "ie";
break;
case "chrome":
defaultBrowser = "chrome";
break;
}
}
catch (ex) {
Cu.reportError("Could not retrieve default browser: " + ex);
}
#endif
// If we found the default browser and we have support for that browser,
// make sure to check it before any other browser, by moving it to the head
// of the array.
if (defaultBrowser)
migratorsOrdered.sort(function(a, b) b == defaultBrowser ? 1 : 0);
for (let i = 0; i < migratorsOrdered.length; i++) {
let migrator = this._getMigratorIfSourceExists(migratorsOrdered[i]);
if (migrator)
return [migratorsOrdered[i], migrator];
}
return ["", null];
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIProfileMigrator]),
classDescription: "Profile Migrator",
contractID: "@mozilla.org/toolkit/profile-migrator;1",
classID: Components.ID("6F8BB968-C14F-4D6F-9733-6C6737B35DCE")
};
let NSGetFactory = XPCOMUtils.generateNSGetFactory([ProfileMigrator]);

View File

@ -1,252 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The Browser Profile Migrator.
*
* The Initial Developer of the Original Code is Ben Goodger.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@bengoodger.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsProfileMigrator.h"
#include "nsIBrowserProfileMigrator.h"
#include "nsIComponentManager.h"
#include "nsIDOMWindow.h"
#include "nsILocalFile.h"
#include "nsIObserverService.h"
#include "nsIProperties.h"
#include "nsIServiceManager.h"
#include "nsISupportsPrimitives.h"
#include "nsIMutableArray.h"
#include "nsIToolkitProfile.h"
#include "nsIToolkitProfileService.h"
#include "nsIWindowWatcher.h"
#include "nsCOMPtr.h"
#include "nsBrowserCompsCID.h"
#include "nsComponentManagerUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "nsServiceManagerUtils.h"
#include "nsStringAPI.h"
#include "nsUnicharUtils.h"
#ifdef XP_WIN
#include <windows.h>
#include "nsIWindowsRegKey.h"
#include "nsILocalFileWin.h"
#else
#include <limits.h>
#endif
#include "nsAutoPtr.h"
///////////////////////////////////////////////////////////////////////////////
// nsIProfileMigrator
#define MIGRATION_WIZARD_FE_URL "chrome://browser/content/migration/migration.xul"
#define MIGRATION_WIZARD_FE_FEATURES "chrome,dialog,modal,centerscreen,titlebar"
NS_IMETHODIMP
nsProfileMigrator::Migrate(nsIProfileStartup* aStartup)
{
nsresult rv;
nsCAutoString key;
nsCOMPtr<nsIBrowserProfileMigrator> bpm;
rv = GetDefaultBrowserMigratorKey(key, bpm);
if (NS_FAILED(rv)) return rv;
if (!bpm) {
nsCAutoString contractID(NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX);
contractID.Append(key);
bpm = do_CreateInstance(contractID.get());
if (!bpm) return NS_ERROR_FAILURE;
}
bool sourceExists;
bpm->GetSourceExists(&sourceExists);
if (!sourceExists) {
#ifdef XP_WIN
// The "Default Browser" key in the registry was set to a browser for which
// no profile data exists. On Windows, this means the Default Browser settings
// in the registry are bad, and we should just fall back to IE in this case.
bpm = do_CreateInstance(NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "ie");
#else
return NS_ERROR_FAILURE;
#endif
}
nsCOMPtr<nsISupportsCString> cstr
(do_CreateInstance("@mozilla.org/supports-cstring;1"));
if (!cstr) return NS_ERROR_OUT_OF_MEMORY;
cstr->SetData(key);
// By opening the Migration FE with a supplied bpm, it will automatically
// migrate from it.
nsCOMPtr<nsIWindowWatcher> ww(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
nsCOMPtr<nsIMutableArray> params = do_CreateInstance(NS_ARRAY_CONTRACTID);
if (!ww || !params) return NS_ERROR_FAILURE;
params->AppendElement(cstr, false);
params->AppendElement(bpm, false);
params->AppendElement(aStartup, false);
nsCOMPtr<nsIDOMWindow> migrateWizard;
return ww->OpenWindow(nsnull,
MIGRATION_WIZARD_FE_URL,
"_blank",
MIGRATION_WIZARD_FE_FEATURES,
params,
getter_AddRefs(migrateWizard));
}
///////////////////////////////////////////////////////////////////////////////
// nsProfileMigrator
NS_IMPL_ISUPPORTS1(nsProfileMigrator, nsIProfileMigrator)
#ifdef XP_WIN
#define INTERNAL_NAME_IEXPLORE "iexplore"
#define INTERNAL_NAME_MOZILLA_SUITE "apprunner"
#define INTERNAL_NAME_CHROME "chrome"
#define INTERNAL_NAME_FIREFOX "firefox"
#endif
nsresult
nsProfileMigrator::GetDefaultBrowserMigratorKey(nsACString& aKey,
nsCOMPtr<nsIBrowserProfileMigrator>& bpm)
{
#if XP_WIN
nsCOMPtr<nsIWindowsRegKey> regKey =
do_CreateInstance("@mozilla.org/windows-registry-key;1");
if (!regKey)
return NS_ERROR_FAILURE;
NS_NAMED_LITERAL_STRING(kCommandKey,
"SOFTWARE\\Classes\\HTTP\\shell\\open\\command");
if (NS_FAILED(regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE,
kCommandKey, nsIWindowsRegKey::ACCESS_READ)))
return NS_ERROR_FAILURE;
nsAutoString value;
if (NS_FAILED(regKey->ReadStringValue(EmptyString(), value)))
return NS_ERROR_FAILURE;
PRInt32 len = value.Find(NS_LITERAL_STRING(".exe"), CaseInsensitiveCompare);
if (len == -1)
return NS_ERROR_FAILURE;
// Move past ".exe"
len += 4;
PRUint32 start = 0;
// skip an opening quotation mark if present
if (value.get()[1] != ':') {
start = 1;
--len;
}
const nsDependentSubstring filePath(Substring(value, start, len));
// We want to find out what the default browser is but the path in and of itself
// isn't enough. Why? Because sometimes on Windows paths get truncated like so:
// C:\PROGRA~1\MOZILL~2\MOZILL~1.EXE
// How do we know what product that is? Mozilla or Mozilla Firebird? etc. Mozilla's
// file objects do nothing to 'normalize' the path so we need to attain an actual
// product descriptor from the file somehow, and in this case it means getting
// the "InternalName" field of the file's VERSIONINFO resource.
//
// In the file's resource segment there is a VERSIONINFO section that is laid
// out like this:
//
// VERSIONINFO
// StringFileInfo
// <TranslationID>
// InternalName "iexplore"
// VarFileInfo
// Translation <TranslationID>
//
// By Querying the VERSIONINFO section for its Tranlations, we can find out where
// the InternalName lives. (A file can have more than one translation of its
// VERSIONINFO segment, but we just assume the first one).
nsCOMPtr<nsILocalFile> lf;
NS_NewLocalFile(filePath, true, getter_AddRefs(lf));
if (!lf)
return NS_ERROR_FAILURE;
nsCOMPtr<nsILocalFileWin> lfw = do_QueryInterface(lf);
if (!lfw)
return NS_ERROR_FAILURE;
nsAutoString internalName;
if (NS_FAILED(lfw->GetVersionInfoField("InternalName", internalName)))
return NS_ERROR_FAILURE;
if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_IEXPLORE)) {
aKey = "ie";
return NS_OK;
}
else if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_CHROME)) {
aKey = "chrome";
return NS_OK;
}
else if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_FIREFOX)) {
aKey = "firefox";
return NS_OK;
}
#else
bool exists = false;
#define CHECK_MIGRATOR(browser) do {\
bpm = do_CreateInstance(NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX browser);\
if (bpm)\
bpm->GetSourceExists(&exists);\
if (exists) {\
aKey = browser;\
return NS_OK;\
}} while(0)
#if defined(XP_MACOSX)
CHECK_MIGRATOR("safari");
#endif
CHECK_MIGRATOR("chrome");
CHECK_MIGRATOR("firefox");
#undef CHECK_MIGRATOR
#endif
return NS_ERROR_FAILURE;
}

View File

@ -1,64 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is The Browser Profile Migrator.
*
* The Initial Developer of the Original Code is Ben Goodger.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ben Goodger <ben@bengoodger.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef profilemigrator___h___
#define profilemigrator___h___
#include "nsIBrowserProfileMigrator.h"
#include "nsIProfileMigrator.h"
#include "nsCOMPtr.h"
#define NS_FIREFOX_PROFILEMIGRATOR_CID \
{ 0x4ca3c946, 0x5408, 0x49f0, { 0x9e, 0xca, 0x3a, 0x97, 0xd5, 0xc6, 0x77, 0x50 } }
class nsProfileMigrator : public nsIProfileMigrator
{
public:
NS_DECL_NSIPROFILEMIGRATOR
NS_DECL_ISUPPORTS
nsProfileMigrator() { }
protected:
~nsProfileMigrator() { }
nsresult GetDefaultBrowserMigratorKey(nsACString& key,
nsCOMPtr<nsIBrowserProfileMigrator>& bpm);
};
#endif

View File

@ -73,7 +73,8 @@ interface nsIProfileStartup : nsISupports
interface nsIProfileMigrator : nsISupports
{
/**
* Do profile migration.
* Migrate data from an outside source, if possible. Does nothing
* otherwise.
*
* When this method is called, a default profile has been created;
* XPCOM has been initialized such that compreg.dat is in the
@ -85,7 +86,7 @@ interface nsIProfileMigrator : nsISupports
* If your migrator needs to access services that use the profile (to
* set profile prefs or bookmarks, for example), use aStartup.doStartup.
*
* The startup code ignores COM exceptions thrown from this method.
* @note The startup code ignores COM exceptions thrown from this method.
*/
void migrate(in nsIProfileStartup aStartup);
};