Bug 293461 - Make safe mode a system option and make handling by the EM less fragile. Also fixes bug 275529 - allows app ID and extension ID to be a prettyname@vendor.tld instead of {GUID}. r=darin+robstrong a=asa

This commit is contained in:
bsmedberg%covad.net 2005-05-12 13:23:30 +00:00
Родитель 63da3fee46
Коммит 96622a4250
21 изменённых файлов: 412 добавлений и 434 удалений

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

@ -44,12 +44,13 @@
#include "nsBuildID.h"
static const nsXREAppData kAppData = {
sizeof(nsXREAppData),
nsnull,
"Mozilla",
"Firefox",
NS_STRINGIFY(APP_VERSION),
NS_STRINGIFY(BUILD_ID),
// ec8030f7-c20a-464f-9b0e-13a3a9e97384
{ 0xec8030f7, 0xc20a, 0x464f, { 0x9b, 0x0e, 0x13, 0xa3, 0xa9, 0xe9, 0x73, 0x84 } },
"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}",
"Copyright (c) 1998 - 2005 mozilla.org",
NS_XRE_ENABLE_PROFILE_MIGRATOR |
NS_XRE_ENABLE_EXTENSION_MANAGER

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

@ -71,6 +71,7 @@ REQUIRES = xpcom \
docshell \
xpconnect \
jar \
xulapp \
$(NULL)
CPPSRCS = \

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

@ -60,6 +60,7 @@
#include "nsString.h"
#include "nsWidgetsCID.h"
#include "nsXPIDLString.h"
#include "nsXULAppAPI.h"
#include "nsIAtom.h"
#include "nsIBindingManager.h"
@ -94,6 +95,7 @@
#include "nsIStyleSheet.h"
#include "nsISupportsArray.h"
#include "nsIWindowMediator.h"
#include "nsIXULRuntime.h"
// keep all the RDF stuff together, in case we can remove it in the far future
#include "rdf.h"
@ -113,8 +115,6 @@
#define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
#define SELECTED_LOCALE_PREF "general.useragent.locale"
#define SELECTED_SKIN_PREF "general.skins.selectedSkin"
#define DSS_SKIN_TO_SELECT "extensions.lastSelectedSkin"
#define DSS_SWITCH_PENDING "extensions.dss.switchPending"
static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID);
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
@ -476,11 +476,23 @@ nsChromeRegistry::Init()
// before we are actually fully initialized.
gChromeRegistry = this;
nsCOMPtr<nsIPrefBranch2> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
PRBool safeMode = PR_FALSE;
nsCOMPtr<nsIXULRuntime> xulrun (do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
if (xulrun)
xulrun->GetInSafeMode(&safeMode);
nsCOMPtr<nsIPrefService> prefserv (do_GetService(NS_PREFSERVICE_CONTRACTID));
nsCOMPtr<nsIPrefBranch> prefs;
if (safeMode)
prefserv->GetDefaultBranch(nsnull, getter_AddRefs(prefs));
else
prefs = do_QueryInterface(prefserv);
if (!prefs) {
NS_WARNING("Could not get pref service!");
}
PRBool useLocalePref = PR_TRUE;
if (prefs) {
@ -507,15 +519,18 @@ nsChromeRegistry::Init()
if (NS_SUCCEEDED(rv))
mSelectedSkin = provider;
rv = prefs->AddObserver(SELECTED_SKIN_PREF, this, PR_TRUE);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't add skin-switching observer!");
nsCOMPtr<nsIPrefBranch2> prefs2 (do_QueryInterface(prefs));
if (prefs2)
rv = prefs2->AddObserver(SELECTED_SKIN_PREF, this, PR_TRUE);
if (useLocalePref) {
rv = prefs->GetCharPref(SELECTED_LOCALE_PREF, getter_Copies(provider));
if (NS_SUCCEEDED(rv))
mSelectedLocale = provider;
prefs->AddObserver(SELECTED_LOCALE_PREF, this, PR_TRUE);
if (prefs2)
prefs2->AddObserver(SELECTED_LOCALE_PREF, this, PR_TRUE);
}
}

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

@ -45,12 +45,13 @@
#include "prtypes.h"
static const nsXREAppData kAppData = {
0,
sizeof(nsXREAppData),
nsnull,
nsnull,
"Thunderbird",
NS_STRINGIFY(APP_VERSION),
NS_STRINGIFY(BUILD_ID),
// {3550f703-e582-4d05-9a08-453d09bdfdc6}
{ 0x3550f703, 0xe582, 0x4d05, { 0x9a, 0x08, 0x45, 0x3d, 0x09, 0xbd, 0xfd, 0xc6 } },
"{3550f703-e582-4d05-9a08-453d09bdfdc6}",
"Copyright (c) 2005 mozilla.org",
NS_XRE_ENABLE_PROFILE_MIGRATOR |
NS_XRE_ENABLE_EXTENSION_MANAGER

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

@ -112,8 +112,8 @@ NS_IMPL_THREADSAFE_RELEASE(nsPrefBranch)
NS_INTERFACE_MAP_BEGIN(nsPrefBranch)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrefBranch)
NS_INTERFACE_MAP_ENTRY(nsIPrefBranch)
NS_INTERFACE_MAP_ENTRY(nsIPrefBranch2)
NS_INTERFACE_MAP_ENTRY(nsIPrefBranchInternal)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIPrefBranch2, !mIsDefault)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIPrefBranchInternal, !mIsDefault)
NS_INTERFACE_MAP_ENTRY(nsISecurityPref)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)

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

@ -17,6 +17,7 @@ installSuccess=Install completed successfully
installWaiting=Waiting...
installInstalling=Installing...
droppedInWarning=The following items were found in your Extensions folder. Do you want to install them?
disabledBySafeMode=%S is disabled by safe mode.
extensions.update.url=https://addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%
extensions.getMoreExtensionsURL=https://addons.mozilla.org/extensions/?application=%APPID%

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

@ -45,10 +45,12 @@ var gExtensionManager = null;
var gExtensionsView = null;
var gWindowState = "";
var gGetMoreURL = "";
var gCurrentTheme = "";
var gCurrentTheme = "classic/1.0";
var gDefaultTheme = "classic/1.0";
var gDownloadManager = null;
var gObserverIndex = -1;
var gItemType = -1;
var gApp = null;
const PREF_EXTENSIONS_GETMORETHEMESURL = "extensions.getMoreThemesURL";
const PREF_EXTENSIONS_GETMOREEXTENSIONSURL = "extensions.getMoreExtensionsURL";
@ -57,8 +59,6 @@ const PREF_EXTENSIONS_DSS_SWITCHPENDING = "extensions.dss.switchPending";
const PREF_EM_LAST_SELECTED_SKIN = "extensions.lastSelectedSkin";
const PREF_GENERAL_SKINS_SELECTEDSKIN = "general.skins.selectedSkin";
const KEY_DEFAULT_THEME = "classic/1.0";
const RDFURI_ITEM_ROOT = "urn:mozilla:item:root";
const PREFIX_ITEM_URI = "urn:mozilla:item:";
@ -144,7 +144,9 @@ function Startup()
gExtensionsView.setAttribute("state", gWindowState);
gExtensionManager = Components.classes["@mozilla.org/extensions/manager;1"]
.getService(Components.interfaces.nsIExtensionManager);
gApp = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULAppInfo)
.QueryInterface(Components.interfaces.nsIXULRuntime);
// Extension Command Updating is handled by a command controller.
gExtensionsView.controllers.appendController(gExtensionsViewController);
@ -158,35 +160,22 @@ function Startup()
var pref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
var defaultPref = pref.QueryInterface(Components.interfaces.nsIPrefService)
.getDefaultBranch(null);
if (!isExtensions) {
gExtensionsView.addEventListener("richview-select", onThemeSelect, false);
if (pref.prefHasUserValue(PREF_EM_LAST_SELECTED_SKIN))
gCurrentTheme = pref.getCharPref(PREF_EM_LAST_SELECTED_SKIN);
else if (pref.prefHasUserValue(PREF_GENERAL_SKINS_SELECTEDSKIN))
gCurrentTheme = pref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
if (!gCurrentTheme)
gCurrentTheme = KEY_DEFAULT_THEME;
try {
gCurrentTheme = pref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
gDefaultTheme = defaultPref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
}
catch (e) { }
var useThemeButton = document.getElementById("useThemeButton");
useThemeButton.hidden = false;
var optionsButton = document.getElementById("optionsButton");
optionsButton.hidden = true;
var pref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
if (!pref.getBoolPref(PREF_EXTENSIONS_DSS_ENABLED) &&
pref.getBoolPref(PREF_EXTENSIONS_DSS_SWITCHPENDING) &&
pref.prefHasUserValue(PREF_EM_LAST_SELECTED_SKIN)) {
var lastSelectedSkin = pref.getCharPref(PREF_EM_LAST_SELECTED_SKIN);
for (var i = 0; i < gExtensionsView.childNodes.length; ++i) {
var item = gExtensionsView.childNodes[i];
if (item.getAttribute("internalName") == lastSelectedSkin)
break;
}
setRestartMessage(item);
}
}
// Restore the last-selected extension
@ -708,10 +697,11 @@ var gExtensionsViewController = {
case "cmd_options":
return selectedItem &&
!selectedItem.disabled &&
!gApp.inSafeMode &&
selectedItem.getAttribute("toBeUninstalled") != "true" &&
selectedItem.getAttribute("optionsURL") != "";
case "cmd_about":
return selectedItem &&
return selectedItem &&
selectedItem.getAttribute("toBeInstalled") != "true" &&
(selectedItem.disabled ? selectedItem.getAttribute("aboutURL") == "" : true);
case "cmd_homepage":
@ -721,7 +711,7 @@ var gExtensionsViewController = {
// uninstall is only available if the selected item isn't the
// default theme.
return (selectedItem &&
selectedItem.getAttribute("internalName") != KEY_DEFAULT_THEME);
selectedItem.getAttribute("internalName") != gDefaultTheme);
}
return selectedItem &&
selectedItem.getAttribute("toBeUninstalled") != "true" &&
@ -737,13 +727,11 @@ var gExtensionsViewController = {
case "cmd_reallyEnable":
// controls whether to show Enable or Disable in extensions' context menu
return selectedItem &&
selectedItem.disabled &&
!gExtensionManager.inSafeMode;
selectedItem.disabled;
case "cmd_enable":
//controls wheter the Enable/Disable menuitem is enabled
return selectedItem &&
selectedItem.disabled &&
!gExtensionManager.inSafeMode &&
selectedItem.getAttribute("toBeUninstalled") != "true" &&
selectedItem.getAttribute("compatible") != "false";
case "cmd_disable":

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

@ -181,7 +181,7 @@ interface nsIExtensionDownloadListener : nsISupports
* XXXben - Some of this stuff should go into a management-ey interface,
* some into an app-startup-ey interface.
*/
[scriptable, uuid(7b77761f-6737-4b77-abed-c82f35a57a90)]
[scriptable, uuid(285adb6e-f2e6-4e19-885d-1fbdad4fb400)]
interface nsIExtensionManager : nsISupports
{
/**
@ -280,11 +280,6 @@ interface nsIExtensionManager : nsISupports
in unsigned long itemCount,
in unsigned long versionUpdateOnly);
/**
* Whether or not the application is currently in safe mode.
*/
readonly attribute boolean inSafeMode;
/**
* Gets a nsIUpdateItem for the item with the specified id.
* @param id

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

@ -55,7 +55,6 @@ const PREF_EM_APP_EXTENSIONS_VERSION = "app.extensions.version";
const PREF_EM_LAST_APP_VERSION = "extensions.lastAppVersion";
const PREF_UPDATE_COUNT = "extensions.update.count";
const PREF_UPDATE_DEFAULT_URL = "extensions.update.url";
const PREF_EM_WASINSAFEMODE = "extensions.wasInSafeMode";
const PREF_EM_IGNOREMTIMECHANGES = "extensions.ignoreMTimeChanges";
const PREF_EM_DISABLEDOBSOLETE = "extensions.disabledObsolete";
const PREF_EM_LAST_SELECTED_SKIN = "extensions.lastSelectedSkin";
@ -83,7 +82,6 @@ const FILE_AUTOREG = ".autoreg";
const FILE_INSTALL_MANIFEST = "install.rdf";
const FILE_CONTENTS_MANIFEST = "contents.rdf";
const FILE_CHROME_MANIFEST = "chrome.manifest";
const FILE_WASINSAFEMODE = "Safe Mode";
const FILE_INSTALLED_EXTENSIONS = "installed-extensions.txt"
const FILE_INSTALLED_EXTENSIONS_PROCESSED = "installed-extensions-processed.txt"
#expand const TARGET_OS = __OSARCH__;
@ -165,7 +163,7 @@ var gLoggingEnabled = null;
/**
* Valid GUIDs fit this pattern.
*/
var gGUIDTest = /(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\})\/?$/i;
var gIDTest = /^(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)\/?$/i;
/**
* Creates a Version Checker object.
@ -551,6 +549,13 @@ function getURIFromFile(file) {
return ioServ.newFileURI(file);
}
/**
* @returns Whether or not we are currently running in safe mode.
*/
function inSafeMode() {
return gApp.inSafeMode;
}
/**
* Extract the string value from a RDF Literal or Resource
* @param literalOrResource
@ -928,7 +933,7 @@ DirectoryInstallLocation.prototype = {
if (!entry)
break;
entry instanceof nsILocalFile;
if (!entry.isDirectory() && gGUIDTest.test(entry.leafName)) {
if (!entry.isDirectory() && gIDTest.test(entry.leafName)) {
var linkedDirectory = this._readDirectoryFromFile(entry);
if (linkedDirectory && linkedDirectory.exists() &&
linkedDirectory.isDirectory()) {
@ -956,12 +961,12 @@ DirectoryInstallLocation.prototype = {
* actually maintained by this Install Location.
*/
getIDForLocation: function(file) {
var section = file.path;
var section = file.leafName;
var filePD = file.persistentDescriptor;
if (filePD in this._locationToIDMap)
section = this._locationToIDMap[filePD];
if (gGUIDTest.test(section))
if (gIDTest.test(section))
return RegExp.$1;
return undefined;
},
@ -1896,7 +1901,7 @@ var StartupCache = {
/**
* Writes the Startup Cache to disk
*/
write: function() {
write: function() {
var extensionsCacheFile = getFile(KEY_PROFILEDIR, [FILE_EXTENSIONS_STARTUP_CACHE]);
var fos = openSafeFileOutputStream(extensionsCacheFile);
for (var locationKey in this.entries) {
@ -1927,7 +1932,8 @@ var StartupCache = {
*/
function ExtensionManager() {
gApp = Components.classes["@mozilla.org/xre/app-info;1"]
.getService(Components.interfaces.nsIXULAppInfo);
.getService(Components.interfaces.nsIXULAppInfo)
.QueryInterface(Components.interfaces.nsIXULRuntime);
gPref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch2);
gLoggingEnabled = getBoolPrefWithDefault(PREF_EM_LOGGING_ENABLED, false);
@ -2044,85 +2050,6 @@ ExtensionManager.prototype = {
gInstallManifestRoot = null;
},
/**
* Cleans up on the first run after a Safe Mode run - re-enables temporarily
* disabled extensions and re-selects the user selected theme.
* @returns true if the application was in Safe Mode previously and Extensions
* have been re-enabled (requiring a restart to load their components)
* false if the application was not in Safe Mode.
*/
_cleanupAfterSafeMode: function() {
var wasInSafeModeFile = getFile(KEY_PROFILEDIR, [DIR_EXTENSIONS, FILE_WASINSAFEMODE]);
if (!wasInSafeModeFile.exists())
return false;
// Clean up after we were in safe mode
try {
this._ensureDS();
this._updateExtensionsManifest(false);
// Retrieve the skin that was selected prior to entering safe mode
// and select it.
var lastSelectedSkin = KEY_DEFAULT_THEME;
try {
lastSelectedSkin = gPref.getCharPref(PREF_EM_LAST_SELECTED_SKIN);
gPref.clearUserPref(PREF_EM_LAST_SELECTED_SKIN);
gPref.setCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN, lastSelectedSkin);
}
catch (e) {
}
wasInSafeModeFile.remove(false);
}
catch (e) {
LOG("ExtensionManager:start - failure, catching exception ... = " + e);
}
return true;
},
/**
* Start the application in Safe Mode (All Extensions disabled for this run,
* using default theme).
* @returns true if we are entering safe mode for the first time since a run
* that was NOT a safe mode run (and as such the system needs to
* restart to unload extension components), false otherwise.
*/
_enterSafeMode: function() {
try {
// Enter safe mode
this._ensureDS();
// Save the current theme (assumed to be the theme that styles the global
// package) and re-select the default theme ("classic/1.0")
if (!gPref.prefHasUserValue(PREF_EM_LAST_SELECTED_SKIN)) {
gPref.setCharPref(PREF_EM_LAST_SELECTED_SKIN,
getCharPrefWithDefault(PREF_GENERAL_SKINS_SELECTEDSKIN,
"classic/1.0"));
if (gPref.prefHasUserValue(PREF_GENERAL_SKINS_SELECTEDSKIN))
gPref.clearUserPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
}
this._ds.safeMode = true;
var needsRestart = true;
var wasInSafeModeFile = getFile(KEY_PROFILEDIR, [DIR_EXTENSIONS, FILE_WASINSAFEMODE]);
if (!wasInSafeModeFile.exists()) {
wasInSafeModeFile.create(nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
this._updateExtensionsManifest(false);
}
else {
// If the "Safe Mode" file already exists, then we are in the second launch of an
// app launched with -safe-mode and so we don't want to provoke any further
// restarts or re-create the file, just continue starting normally.
needsRestart = false;
}
}
catch (e) {
LOG("nsExtensionManager:start - (safe mode) failure, catching exception ... " + e);
}
return needsRestart;
},
/**
* Check for presence of critical Extension system files. If any is missing,
* delete the others and signal that the system needs to rebuild them all
@ -2167,8 +2094,6 @@ ExtensionManager.prototype = {
* See nsIExtensionManager.idl
*/
start: function(commandLine, isDirty) {
var needsRestart = false;
// Somehow the component list went away, and for that reason the new one
// generated by this function is going to result in a different compreg.
// We must force a restart.
@ -2176,33 +2101,25 @@ ExtensionManager.prototype = {
if (!componentList.exists())
isDirty = true;
var safeMode = commandLine.handleFlag("safe-mode", false);
if (!safeMode) {
if (this._cleanupAfterSafeMode())
needsRestart = true;
// Check for missing manifests - e.g. missing extensions.ini, missing
// extensions-startup.manifest, extensions.rdf etc. If any of these files
// is missing then we are in some kind of weird or initial state and need
// to force a regeneration.
if (this._ensureDatasetIntegrity())
isDirty = true;
// Check for missing manifests - e.g. missing extensions.ini, missing
// extensions-startup.manifest, extensions.rdf etc. If any of these files
// is missing then we are in some kind of weird or initial state and need
// to force a regeneration.
if (this._ensureDatasetIntegrity())
isDirty = true;
// Configure any items that are being installed, uninstalled or upgraded
// by being added, removed or modified by another process. We must do this
// on every startup since there is no way we can tell if this has happened
// or not!
if (this._checkForFileChanges())
isDirty = true;
// Extension Changes OR exiting Safe Mode (isDirty not set in this case)
if (isDirty || needsRestart)
needsRestart = needsRestart || this._finishOperations();
}
else
needsRestart = this._enterSafeMode();
// Configure any items that are being installed, uninstalled or upgraded
// by being added, removed or modified by another process. We must do this
// on every startup since there is no way we can tell if this has happened
// or not!
if (this._checkForFileChanges())
isDirty = true;
return needsRestart;
// Extension Changes
if (isDirty)
return this._finishOperations();
return false;
},
/**
@ -2585,6 +2502,9 @@ ExtensionManager.prototype = {
* otherwise.
*/
_upgradeExtensionChrome: function() {
if (inSafeMode())
return false;
var checkForNewChrome = false;
var ds = this.datasource;
// If we have extensions that were installed before the new flat chrome
@ -2619,6 +2539,9 @@ ExtensionManager.prototype = {
* otherwise.
*/
_upgradeThemeChrome: function() {
if (inSafeMode())
return false;
var checkForNewChrome = false;
var themes = this._getActiveItems(nsIUpdateItem.TYPE_THEME);
for (i = 0; i < themes.length; ++i) {
@ -2837,13 +2760,6 @@ ExtensionManager.prototype = {
return needsRestart;
},
/**
* @returns Whether or not we are currently running in safe mode.
*/
get inSafeMode() {
return this.datasource.safeMode;
},
/**
* Write the Extensions List and the Startup Cache
* @param needsRestart
@ -2864,7 +2780,7 @@ ExtensionManager.prototype = {
* @returns An array of active items of the specified type.
*/
_getActiveItems: function(type) {
if (this.datasource.safeMode)
if (inSafeMode())
return [];
var allItems = this.getItemList(type, { });
@ -2953,7 +2869,8 @@ ExtensionManager.prototype = {
else if (!autoregFile.exists())
autoregFile.remove(false);
}
catch (e) {}
catch (e) {
}
return val;
},
@ -3026,14 +2943,14 @@ ExtensionManager.prototype = {
if (data.id == gApp.ID)
installData.currentApp = data;
}
catch (e) {
catch (e) {
continue;
}
}
}
// Validate the Item ID
if (!gGUIDTest.test(installData.id)) {
if (!gIDTest.test(installData.id)) {
installData.error = INSTALLERROR_INVALID_GUID;
return installData;
}
@ -4070,7 +3987,7 @@ ExtensionManager.prototype = {
*/
get datasource() {
this._ensureDS();
return this._ds;
return this._ds.QueryInterface(Components.interfaces.nsIRDFDataSource);
},
/**
@ -4555,7 +4472,7 @@ RDFItemUpdater.prototype = {
if (rv === undefined)
throw Components.results.NS_ERROR_FAILURE;
}
catch (e) {
catch (e) {
// XXXben show console message "aProperty" not found on aSourceResource.
return null;
}
@ -4684,7 +4601,6 @@ function ExtensionsDataSource(em) {
ExtensionsDataSource.prototype = {
_inner : null,
_em : null,
safeMode : false,
_itemRoot : null,
_defaultTheme : null,
@ -4702,7 +4618,7 @@ ExtensionsDataSource.prototype = {
// The Default Theme is always compatible.
if (source.EqualsNode(this._defaultTheme))
return true;
var appVersion = getCharPrefWithDefault(PREF_EM_APP_EXTENSIONS_VERSION,
gApp.version);
var appID = gApp.ID;
@ -5493,18 +5409,15 @@ ExtensionsDataSource.prototype = {
},
/**
* Get the em:disabled property (RDFLiteral true if this item is disabled
* because we're in safe mode, null otherwise (read the actual value from
* the datasource).
* If we're in safe mode, force the generic about dialog for all extensions.
*/
_rdfGet_disabled: function(item, property) {
// Ensure the Default Theme is always enabled, so the user can switch back
// to it easily from Safe Mode.
if (this.safeMode && !item.EqualsNode(this._defaultTheme))
return EM_L("true");
_rdfGet_aboutURL: function(item, property) {
if (inSafeMode())
return EM_L("");
return null;
},
},
/**
* Get the em:compatible property (whether or not this item is compatible)
*/
@ -5572,6 +5485,9 @@ ExtensionsDataSource.prototype = {
return getLiteral("incompatibleExtension", BundleManager.appName, gApp.version);
}
if (inSafeMode())
return getLiteral("disabledBySafeMode", itemName, BundleManager.appName);
// No special state for this item, so just use the "description" property.
return this.GetTarget(item, EM_R("description"), true);
},
@ -5629,7 +5545,7 @@ ExtensionsDataSource.prototype = {
_rdfGet_homepageURL: function(item, property) {
return this._getLocalizablePropertyValue(item, property);
},
/**
* See nsIRDFDataSource.idl
*/

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

@ -89,6 +89,7 @@ FORCE_STATIC_LIB = 1
XPIDLSRCS = \
nsINativeAppSupport.idl \
nsIXULAppInfo.idl \
nsIXULRuntime.idl \
$(NULL)
EXPORTS = nsXULAppAPI.h

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

@ -71,6 +71,7 @@
#include "nsIDOMWindow.h"
#include "nsIEventQueueService.h"
#include "nsIExtensionManager.h"
#include "nsIFastLoadService.h" // for PLATFORM_FASL_SUFFIX
#include "nsIIOService.h"
#include "nsIObserverService.h"
#include "nsINativeAppSupport.h"
@ -89,6 +90,7 @@
#include "nsIWindowMediator.h"
#include "nsIWindowWatcher.h"
#include "nsIXULAppInfo.h"
#include "nsIXULRuntime.h"
#include "nsCRT.h"
#include "nsCOMPtr.h"
@ -339,21 +341,26 @@ CheckArg(const char* aArg, const char **aParam = nsnull)
return ARG_NONE;
}
PRBool gSafeMode = PR_FALSE;
/**
* The nsXULAppInfo object implements nsIFactory so that it can be its own
* singleton.
*/
class nsXULAppInfo : public nsIXULAppInfo,
public nsIXULRuntime,
public nsIFactory
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIXULAPPINFO
NS_DECL_NSIXULRUNTIME
NS_DECL_NSIFACTORY
};
NS_IMPL_QUERY_INTERFACE2(nsXULAppInfo,
NS_IMPL_QUERY_INTERFACE3(nsXULAppInfo,
nsIXULAppInfo,
nsIXULRuntime,
nsIFactory)
NS_IMETHODIMP_(nsrefcnt)
@ -371,7 +378,7 @@ nsXULAppInfo::Release()
NS_IMETHODIMP
nsXULAppInfo::GetVendor(nsACString& aResult)
{
aResult.Assign(gAppData->appVendor ? gAppData->appVendor : "");
aResult.Assign(gAppData->vendor);
return NS_OK;
}
@ -379,19 +386,15 @@ nsXULAppInfo::GetVendor(nsACString& aResult)
NS_IMETHODIMP
nsXULAppInfo::GetName(nsACString& aResult)
{
aResult.Assign(gAppData->appName);
aResult.Assign(gAppData->name);
return NS_OK;
}
NS_IMETHODIMP
nsXULAppInfo::GetID(nsID** aResult)
nsXULAppInfo::GetID(nsACString& aResult)
{
*aResult = (nsID*) NS_Alloc(sizeof(nsID));
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
**aResult = gAppData->id;
aResult.Assign(gAppData->ID);
return NS_OK;
}
@ -399,7 +402,7 @@ nsXULAppInfo::GetID(nsID** aResult)
NS_IMETHODIMP
nsXULAppInfo::GetVersion(nsACString& aResult)
{
aResult.Assign(gAppData->appVersion ? gAppData->appVersion : "");
aResult.Assign(gAppData->version);
return NS_OK;
}
@ -407,7 +410,7 @@ nsXULAppInfo::GetVersion(nsACString& aResult)
NS_IMETHODIMP
nsXULAppInfo::GetAppBuildID(nsACString& aResult)
{
aResult.Assign(gAppData->appBuildID ? gAppData->appBuildID : "");
aResult.Assign(gAppData->buildID);
return NS_OK;
}
@ -420,6 +423,13 @@ nsXULAppInfo::GetGeckoBuildID(nsACString& aResult)
return NS_OK;
}
NS_IMETHODIMP
nsXULAppInfo::GetInSafeMode(PRBool *aResult)
{
*aResult = gSafeMode;
return NS_OK;
}
NS_IMETHODIMP
nsXULAppInfo::CreateInstance(nsISupports* aOuter,
REFNSIID aIID,
@ -712,13 +722,13 @@ DumpHelp()
printf("%s-height <value>%sSet height of startup window to <value>.\n",HELP_SPACER_1,HELP_SPACER_2);
printf("%s-h or -help%sPrint this message.\n",HELP_SPACER_1,HELP_SPACER_2);
printf("%s-width <value>%sSet width of startup window to <value>.\n",HELP_SPACER_1,HELP_SPACER_2);
printf("%s-v or -version%sPrint %s version.\n",HELP_SPACER_1,HELP_SPACER_2, gAppData->appName);
printf("%s-v or -version%sPrint %s version.\n",HELP_SPACER_1,HELP_SPACER_2, gAppData->name);
printf("%s-P <profile>%sStart with <profile>.\n",HELP_SPACER_1,HELP_SPACER_2);
printf("%s-ProfileManager%sStart with profile manager.\n",HELP_SPACER_1,HELP_SPACER_2);
printf("%s-UILocale <locale>%sStart with <locale> resources as UI Locale.\n",HELP_SPACER_1,HELP_SPACER_2);
printf("%s-contentLocale <locale>%sStart with <locale> resources as content Locale.\n",HELP_SPACER_1,HELP_SPACER_2);
#if defined(XP_WIN) || defined(XP_OS2)
printf("%s-console%sStart %s with a debugging console.\n",HELP_SPACER_1,HELP_SPACER_2,gAppData->appName);
printf("%s-console%sStart %s with a debugging console.\n",HELP_SPACER_1,HELP_SPACER_2,gAppData->name);
#endif
// this works, but only after the components have registered. so if you drop in a new command line handler, -help
@ -803,7 +813,7 @@ VerifyInstallation(nsIFile* aAppDir)
static void
DumpVersion()
{
printf("%s %s %s, %s\n", gAppData->appVendor, gAppData->appName, gAppData->appVersion, gAppData->copyright);
printf("%s %s %s, %s\n", gAppData->vendor, gAppData->name, gAppData->version, gAppData->copyright);
}
#ifdef MOZ_ENABLE_XREMOTE
@ -816,7 +826,7 @@ HandleRemoteArgument(const char* remote)
ArgResult ar;
const char *profile = 0;
nsCAutoString program(gAppData->appName);
nsCAutoString program(gAppData->name);
ToLowerCase(program);
const char *username = getenv("LOGNAME");
@ -873,7 +883,7 @@ RemoteCommandLine()
nsresult rv;
ArgResult ar;
nsCAutoString program(gAppData->appName);
nsCAutoString program(gAppData->name);
ToLowerCase(program);
const char *username = getenv("LOGNAME");
@ -1078,7 +1088,7 @@ ProfileLockedDialog(nsILocalFile* aProfileDir, nsILocalFile* aProfileLocalDir,
sbs->CreateBundle(kProfileProperties, getter_AddRefs(sb));
NS_ENSURE_TRUE(sbs, NS_ERROR_FAILURE);
NS_ConvertUTF8toUTF16 appName(gAppData->appName);
NS_ConvertUTF8toUTF16 appName(gAppData->name);
const PRUnichar* params[] = {appName.get(), appName.get()};
nsXPIDLString killMessage;
@ -1473,9 +1483,9 @@ static void GetVersion(nsIFile* aProfileDir, char* aVersion, int aVersionLength)
static void BuildVersion(nsCString &aBuf)
{
aBuf.Assign(gAppData->appVersion);
aBuf.Assign(gAppData->version);
aBuf.Append('_');
aBuf.Append(gAppData->appBuildID);
aBuf.Append(gAppData->buildID);
aBuf.Append('/');
aBuf.AppendLiteral(GRE_BUILD_ID);
}
@ -1519,7 +1529,7 @@ static PRBool ComponentsListChanged(nsIFile* aProfileDir)
return exists;
}
static void RemoveComponentRegistries(nsIFile* aProfileDir)
static void RemoveComponentRegistries(nsIFile* aProfileDir, nsIFile* aLocalProfileDir)
{
nsCOMPtr<nsIFile> file;
aProfileDir->Clone(getter_AddRefs(file));
@ -1534,6 +1544,13 @@ static void RemoveComponentRegistries(nsIFile* aProfileDir)
file->SetNativeLeafName(NS_LITERAL_CSTRING(".autoreg"));
file->Remove(PR_FALSE);
aLocalProfileDir->Clone(getter_AddRefs(file));
if (!file)
return;
file->AppendNative(NS_LITERAL_CSTRING("XUL" PLATFORM_FASL_SUFFIX));
file->Remove(PR_FALSE);
}
const nsXREAppData* gAppData = nsnull;
@ -1604,6 +1621,14 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
gArgv = argv;
NS_ASSERTION(aAppData, "must specify XUL app data");
// In the future when nsXREAppData is extended, this check will need to
// have more finesse.
if (aAppData->size < sizeof(nsXREAppData)) {
NS_ERROR("aAppdata.size isn't set properly!");
return 1;
}
gAppData = aAppData;
gRestartArgc = argc;
@ -1628,6 +1653,9 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
NSGetStaticModuleInfo = app_getModuleInfo;
#endif
if (CheckArg("safe-mode"))
gSafeMode = PR_TRUE;
// Handle -help and -version command line arguments.
// They should return quickly, so we deal with them here.
if (CheckArg("h") || CheckArg("help") || CheckArg("?")) {
@ -1646,16 +1674,7 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
nsXREDirProvider dirProvider;
{
nsCOMPtr<nsIFile> xulAppDir;
const char *appDataFile;
if (CheckArg("app", &appDataFile) == ARG_FOUND) {
nsCOMPtr<nsILocalFile> lf;
XRE_GetFileFromPath(appDataFile, getter_AddRefs(lf));
lf->GetParent(getter_AddRefs(xulAppDir));
}
rv = dirProvider.Initialize(xulAppDir);
rv = dirProvider.Initialize(gAppData->directory);
if (NS_FAILED(rv))
return 1;
}
@ -1696,7 +1715,7 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
_g_set_application_name_fn _g_set_application_name =
(_g_set_application_name_fn)PR_FindFunctionSymbolAndLibrary("g_set_application_name", &glib2);
if (_g_set_application_name) {
_g_set_application_name(gAppData->appName);
_g_set_application_name(gAppData->name);
}
if (glib2) {
PR_UnloadLibrary(glib2);
@ -1815,15 +1834,19 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
// there is no need for re-registration. If the user loads the same
// profile in different builds the component registry must be
// re-generated to prevent mysterious component loading failures.
//
if (version.Equals(lastVersion)) {
//
if (gSafeMode) {
RemoveComponentRegistries(profD, profLD);
WriteVersion(profD, NS_LITERAL_CSTRING("Safe Mode"));
}
else if (version.Equals(lastVersion)) {
componentsListChanged = ComponentsListChanged(profD);
if (componentsListChanged) {
// Remove compreg.dat and xpti.dat, forcing component re-registration,
// with the new list of additional components directories specified
// in "components.ini" which we have just discovered changed since the
// last time the application was run.
RemoveComponentRegistries(profD);
RemoveComponentRegistries(profD, profLD);
}
// Nothing need be done for the normal startup case.
}
@ -1831,7 +1854,7 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
// Remove compreg.dat and xpti.dat, forcing component re-registration
// with the default set of components (this disables any potentially
// troublesome incompatible XPCOM components).
RemoveComponentRegistries(profD);
RemoveComponentRegistries(profD, profLD);
// Tell the Extension Manager it should check for incompatible
// Extensions and re-write the Components manifest ("components.ini")
@ -2001,7 +2024,7 @@ XRE_main(int argc, char* argv[], const nsXREAppData* aAppData)
nsCOMPtr<nsIRemoteService> remoteService;
remoteService = do_GetService("@mozilla.org/toolkit/remote-service;1");
if (remoteService)
remoteService->Startup(gAppData->appName, nsnull);
remoteService->Startup(gAppData->name, nsnull);
#endif /* MOZ_ENABLE_XREMOTE */
// enable win32 DDE responses and Mac appleevents responses

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

@ -69,6 +69,7 @@ class nsIProfileUnlocker;
extern nsXREDirProvider* gDirServiceProvider;
extern const nsXREAppData* gAppData;
extern PRBool gSafeMode;
extern int gArgc;
extern char **gArgv;

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

@ -37,53 +37,48 @@
#include "nsISupports.idl"
/**
* A scriptable interface to the nsXULAppAPI structure.
* A scriptable interface to the nsXULAppAPI structure. See nsXULAppAPI.h for
* a detailed description of each attribute.
*
* @status IN-FLUX This interface *will* change before it stabilizes. Use at your
* own risk.
* @status UNDER_REVIEW - This interface is under review to be frozen, but
* isn't frozen yet. Use with caution.
*/
[scriptable, uuid(e781bdd9-bc92-4deb-a1e8-8cbf94365ef9)]
[scriptable, uuid(1f4e76cb-414f-4c50-b31e-be52c43502ff)]
interface nsIXULAppInfo : nsISupports
{
/**
* The name of the application vendor. This is ASCII, and is normally
* mixed-case; e.g. "Mozilla". It may not be specified, resulting in the
* empty string.
* @see nsXREAppData.vendor
* @returns an empty string if nsXREAppData.vendor is not set.
*/
readonly attribute ACString vendor;
/**
* The name of the application. This is ASCII, and is normally mixed-case;
* e.g. "Firefox".
* @see nsXREAppData.name
*/
readonly attribute ACString name;
/**
* The version of the application. By tradition, this is in the form
* <major>.<minor>.<release> with an optonal trailing +
* @see nsXREAppData.version
* @returns an empty string if nsXREAppData.version is not set.
*/
readonly attribute ACString version;
/**
* The application GUID.
* @see nsXREAppData.ID
* @returns an empty string if nsXREAppData.ID is not set.
*/
readonly attribute nsIDPtr ID;
readonly attribute ACString ID;
/**
* The build ID/date of the application. For xulrunner applications,
* this will be different than the build ID of gecko. Be careful
* about which one you want. It is in the form YYYYMMDDHH.
* about which one you want.
*/
readonly attribute ACString appBuildID;
/**
* Thie build ID/date of gecko and the xulrunner.
* The build ID/date of gecko and the xulrunner.
*/
readonly attribute ACString geckoBuildID;
/**
* XXXTodo: add app UUID and em-enablement prefs. Also
* think about adding safe-mode.
*/
};

54
toolkit/xre/nsIXULRuntime.idl Executable file
Просмотреть файл

@ -0,0 +1,54 @@
/* ***** 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 Mozilla XUL Toolkit.
*
* The Initial Developer of the Original Code is
* Benjamin Smedberg <benjamin@smedbergs.us>
*
* Portions created by the Initial Developer are Copyright (C) 2005
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 "nsISupports.idl"
/**
* Provides information about the XUL runtime.
* @status UNSTABLE - This interface is not frozen and will probably change in
* future releases. If you need this functionality to be
* stable/frozen, please contact Benjamin Smedberg.
*/
[scriptable, uuid(28e8652b-3e9e-4e35-a8f7-e65f8d2399e0)]
interface nsIXULRuntime : nsISupports
{
/**
* Whether the application was launched in safe mode.
*/
readonly attribute boolean inSafeMode;
};

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

@ -596,7 +596,7 @@ struct MessageWindow {
if ( !mClassName ) {
sprintf( classNameBuffer,
"%s%s",
gAppData->appName,
gAppData->name,
"MessageWindow" );
mClassName = classNameBuffer;
}
@ -793,7 +793,7 @@ nsNativeAppSupportOS2::Start( PRBool *aResult ) {
// Grab mutex first.
// Build mutex name from app name.
PR_snprintf( mMutexName, sizeof mMutexName, "%s%s", gAppData->appName, MOZ_STARTUP_MUTEX_NAME );
PR_snprintf( mMutexName, sizeof mMutexName, "%s%s", gAppData->name, MOZ_STARTUP_MUTEX_NAME );
Mutex startupLock = Mutex( mMutexName );
NS_ENSURE_TRUE( startupLock.Lock( MOZ_DDE_START_TIMEOUT ), NS_ERROR_FAILURE );
@ -898,7 +898,7 @@ nsNativeAppSupportOS2::StartDDE() {
NS_ERROR_FAILURE );
// Allocate DDE strings.
NS_ENSURE_TRUE( ( mApplication = WinDdeCreateStringHandle( (char*) gAppData->appName, CP_WINANSI ) ) && InitTopicStrings(),
NS_ENSURE_TRUE( ( mApplication = WinDdeCreateStringHandle( (char*) gAppData->name, CP_WINANSI ) ) && InitTopicStrings(),
NS_ERROR_FAILURE );
// Next step is to register a DDE service.
@ -1813,7 +1813,7 @@ PRBool StartOS2App(int aArgc, char **aArgv)
memset(&x, 0, sizeof(x));
x.Length = sizeof(x);
(const char* const)(x.PgmTitle) = gAppData->appName;
(const char* const)(x.PgmTitle) = gAppData->name;
x.InheritOpt = SSF_INHERTOPT_PARENT;
x.SessionType = SSF_TYPE_WINDOWABLEVIO;
x.PgmControl = SSF_CONTROL_NOAUTOCLOSE;

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

@ -455,7 +455,7 @@ struct MessageWindow {
::_snprintf( classNameBuffer,
sizeof classNameBuffer,
"%s%s",
gAppData->appName,
gAppData->name,
"MessageWindow" );
mClassName = classNameBuffer;
}
@ -634,7 +634,7 @@ nsNativeAppSupportWin::Start( PRBool *aResult ) {
// Grab mutex first.
// Build mutex name from app name.
::_snprintf( mMutexName, sizeof mMutexName, "%s%s", gAppData->appName, MOZ_STARTUP_MUTEX_NAME );
::_snprintf( mMutexName, sizeof mMutexName, "%s%s", gAppData->name, MOZ_STARTUP_MUTEX_NAME );
Mutex startupLock = Mutex( mMutexName );
NS_ENSURE_TRUE( startupLock.Lock( MOZ_DDE_START_TIMEOUT ), NS_ERROR_FAILURE );
@ -761,7 +761,7 @@ nsNativeAppSupportWin::StartDDE() {
NS_ERROR_FAILURE );
// Allocate DDE strings.
NS_ENSURE_TRUE( ( mApplication = DdeCreateStringHandle( mInstance, (char*) gAppData->appName, CP_WINANSI ) ) && InitTopicStrings(),
NS_ENSURE_TRUE( ( mApplication = DdeCreateStringHandle( mInstance, (char*) gAppData->name, CP_WINANSI ) ) && InitTopicStrings(),
NS_ERROR_FAILURE );
// Next step is to register a DDE service.

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

@ -455,15 +455,9 @@ nsXREDirProvider::GetFiles(const char* aProperty, nsISimpleEnumerator** aResult)
directories.AppendObject(file);
}
static const char *const kAppendCompDir[] = { "components", nsnull };
if (mProfileDir && !gSafeMode) {
static const char *const kAppendCompDir[] = { "components", nsnull };
nsCOMPtr<nsIFile> appFile;
mAppDir->Clone(getter_AddRefs(appFile));
appFile->AppendNative(NS_LITERAL_CSTRING("extensions.ini"));
LoadDirsIntoArray(appFile, "ExtensionDirs",
kAppendCompDir, directories);
if (mProfileDir) {
nsCOMPtr<nsIFile> profileFile;
mProfileDir->Clone(getter_AddRefs(profileFile));
profileFile->AppendNative(NS_LITERAL_CSTRING("extensions.ini"));
@ -476,7 +470,7 @@ nsXREDirProvider::GetFiles(const char* aProperty, nsISimpleEnumerator** aResult)
}
else if (!strcmp(aProperty, NS_APP_PREFS_DEFAULTS_DIR_LIST)) {
nsCOMArray<nsIFile> directories;
if (mXULAppDir) {
nsCOMPtr<nsIFile> file;
mXULAppDir->Clone(getter_AddRefs(file));
@ -487,13 +481,15 @@ nsXREDirProvider::GetFiles(const char* aProperty, nsISimpleEnumerator** aResult)
directories.AppendObject(file);
}
static const char *const kAppendPrefDir[] = { "defaults", "preferences", nsnull };
nsCOMPtr<nsIFile> profileFile;
if (mProfileDir) {
mProfileDir->Clone(getter_AddRefs(profileFile));
profileFile->AppendNative(NS_LITERAL_CSTRING("extensions.ini"));
LoadDirsIntoArray(profileFile, "ExtensionDirs",
kAppendPrefDir, directories);
if (!gSafeMode) {
static const char *const kAppendPrefDir[] = { "defaults", "preferences", nsnull };
nsCOMPtr<nsIFile> profileFile;
if (mProfileDir) {
mProfileDir->Clone(getter_AddRefs(profileFile));
profileFile->AppendNative(NS_LITERAL_CSTRING("extensions.ini"));
LoadDirsIntoArray(profileFile, "ExtensionDirs",
kAppendPrefDir, directories);
}
}
rv = NS_NewArrayEnumerator(aResult, directories);
@ -514,8 +510,8 @@ nsXREDirProvider::GetFiles(const char* aProperty, nsISimpleEnumerator** aResult)
if (NS_SUCCEEDED(file->Exists(&exists)) && exists)
manifests.AppendObject(file);
}
if (mProfileDir) {
if (mProfileDir && !gSafeMode) {
nsCOMPtr<nsIFile> profileFile;
mProfileDir->Clone(getter_AddRefs(profileFile));
profileFile->AppendNative(NS_LITERAL_CSTRING("extensions.ini"));
@ -528,7 +524,7 @@ nsXREDirProvider::GetFiles(const char* aProperty, nsISimpleEnumerator** aResult)
}
else if (!strcmp(aProperty, NS_SKIN_MANIFESTS_FILE_LIST)) {
nsCOMArray<nsIFile> manifests;
if (mProfileDir) {
if (mProfileDir && !gSafeMode) {
nsCOMPtr<nsIFile> profileFile;
mProfileDir->Clone(getter_AddRefs(profileFile));
profileFile->AppendNative(NS_LITERAL_CSTRING("extensions.ini"));
@ -554,7 +550,7 @@ nsXREDirProvider::GetFiles(const char* aProperty, nsISimpleEnumerator** aResult)
directories.AppendObject(file);
}
if (mProfileDir) {
if (mProfileDir && !gSafeMode) {
static const char *const kAppendChromeDir[] = { "chrome", nsnull };
nsCOMPtr<nsIFile> profileFile;
@ -705,7 +701,7 @@ nsXREDirProvider::GetUserDataDirectory(nsILocalFile** aFile, PRBool aLocal)
// Note that MacOS ignores the vendor when creating the profile hierarchy - all
// application preferences directories live alongside one another in
// ~/Library/Application Support/
rv = dirFileMac->AppendNative(nsDependentCString(gAppData->appName));
rv = dirFileMac->AppendNative(nsDependentCString(gAppData->name));
NS_ENSURE_SUCCESS(rv, rv);
#elif defined(XP_WIN)
LPMALLOC pMalloc;
@ -734,18 +730,18 @@ nsXREDirProvider::GetUserDataDirectory(nsILocalFile** aFile, PRBool aLocal)
PR_TRUE, getter_AddRefs(localDir));
NS_ENSURE_SUCCESS(rv, rv);
if (gAppData->appVendor) {
rv = localDir->AppendNative(nsDependentCString(gAppData->appVendor));
if (gAppData->vendor) {
rv = localDir->AppendNative(nsDependentCString(gAppData->vendor));
NS_ENSURE_SUCCESS(rv, rv);
}
rv = localDir->AppendNative(nsDependentCString(gAppData->appName));
rv = localDir->AppendNative(nsDependentCString(gAppData->name));
NS_ENSURE_SUCCESS(rv, rv);
#elif defined(XP_OS2)
#if 0 /* For OS/2 we want to always use MOZILLA_HOME */
// we want an environment variable of the form
// FIREFOX_HOME, etc
nsDependentCString envVar(nsDependentCString(gAppData->appName));
nsDependentCString envVar(nsDependentCString(gAppData->name));
envVar.Append("_HOME");
char *pHome = getenv(envVar.get());
#endif
@ -765,11 +761,11 @@ nsXREDirProvider::GetUserDataDirectory(nsILocalFile** aFile, PRBool aLocal)
}
NS_ENSURE_SUCCESS(rv, rv);
if (gAppData->appVendor) {
rv = localDir->AppendNative(nsDependentCString(gAppData->appVendor));
if (gAppData->vendor) {
rv = localDir->AppendNative(nsDependentCString(gAppData->vendor));
NS_ENSURE_SUCCESS(rv, rv);
}
rv = localDir->AppendNative(nsDependentCString(gAppData->appName));
rv = localDir->AppendNative(nsDependentCString(gAppData->name));
NS_ENSURE_SUCCESS(rv, rv);
#elif defined(XP_BEOS)
@ -785,11 +781,11 @@ nsXREDirProvider::GetUserDataDirectory(nsILocalFile** aFile, PRBool aLocal)
getter_AddRefs(localDir));
NS_ENSURE_SUCCESS(rv, rv);
if (gAppData->appVendor) {
rv = localDir->AppendNative(nsDependentCString(gAppData->appVendor));
if (gAppData->vendor) {
rv = localDir->AppendNative(nsDependentCString(gAppData->vendor));
NS_ENSURE_SUCCESS(rv, rv);
}
rv = localDir->AppendNative(nsDependentCString(gAppData->appName));
rv = localDir->AppendNative(nsDependentCString(gAppData->name));
NS_ENSURE_SUCCESS(rv, rv);
#elif defined(XP_UNIX)
@ -806,18 +802,18 @@ nsXREDirProvider::GetUserDataDirectory(nsILocalFile** aFile, PRBool aLocal)
// Offset 1 for the outermost folder to make it hidden (i.e. using the ".")
char* writing = profileFolderName + 1;
if (gAppData->appVendor) {
GetProfileFolderName(writing, gAppData->appVendor);
if (gAppData->vendor) {
GetProfileFolderName(writing, gAppData->vendor);
rv = localDir->AppendNative(nsDependentCString(profileFolderName));
NS_ENSURE_SUCCESS(rv, rv);
char temp[MAXPATHLEN];
GetProfileFolderName(temp, gAppData->appName);
GetProfileFolderName(temp, gAppData->name);
appNameFolder = temp;
}
else {
GetProfileFolderName(writing, gAppData->appName);
GetProfileFolderName(writing, gAppData->name);
appNameFolder = profileFolderName;
}
rv = localDir->AppendNative(nsDependentCString(appNameFolder));

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

@ -61,8 +61,75 @@
class nsILocalFile;
/**
* This API is "not even kinda frozen yet"
* Application-specific data needed to start the apprunner.
*
* @status UNDER_REVIEW - This API is under review to be frozen, but isn't
* frozen yet. Use with caution.
*/
struct nsXREAppData
{
/**
* This should be set to sizeof(nsXREAppData). This structure may be
* extended in future releases, and this ensures that binary compatibility
* is maintained.
*/
PRUint32 size;
/**
* The directory of the application to be run. May be null if the
* xulrunner and the app are installed into the same directory.
*/
nsILocalFile* directory;
/**
* The name of the application vendor. This must be ASCII, and is normally
* mixed-case, e.g. "Mozilla". Optional (may be null), but highly
* recommended. Must not be the empty string.
*/
const char *vendor;
/**
* The name of the application. This must be ASCII, and is normally
* mixed-case, e.g. "Firefox". Required (must not be null or an empty
* string).
*/
const char *name;
/**
* The major version, e.g. "0.8.0+". Optional (may be null), but
* required for advanced application features such as the extension
* manager and update service. Must not be the empty string.
*/
const char *version;
/**
* The application's build identifier, e.g. "2004051604"
*/
const char *buildID;
/**
* The application's UUID. Used by the extension manager to determine
* compatible extensions. Optional, but required for advanced application
* features such as the extension manager and update service.
*
* This has traditionally been in the form
* "{AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE}" but for new applications
* a more readable form is encouraged: "appname@vendor.tld". Only
* the following characters are allowed: a-z A-Z 0-9 - . @ _ { } *
*/
const char *ID;
/**
* The copyright information to print for the -h commandline flag,
* e.g. "Copyright (c) 2003 mozilla.org".
*/
const char *copyright;
/**
* Combination of NS_XRE_ prefixed flags (defined below).
*/
PRUint32 flags;
};
/**
* Indicates whether or not the profile migrator service may be
@ -76,51 +143,6 @@ class nsILocalFile;
*/
#define NS_XRE_ENABLE_EXTENSION_MANAGER (1 << 2)
/**
* Application-specific data needed to start the apprunner.
*/
struct nsXREAppData
{
/**
* The name of the application vendor. This must be ASCII, and is normally
* mixed-case, e.g. "Mozilla".
*/
const char *appVendor;
/**
* The name of the application. This must be ASCII, and is normally
* mixed-case, e.g. "Firefox".
*/
const char *appName;
/**
* The major version, e.g. "0.8.0+"
*/
const char *appVersion;
/**
* The application's build identifier, e.g. "2004051604"
*/
const char *appBuildID;
/**
* The application's UUID. Used by the extension manager to determine
* compatible extensions.
*/
nsID id;
/**
* The copyright information to print for the -h commandline flag,
* e.g. "Copyright (c) 2003 mozilla.org".
*/
const char *copyright;
/**
* Combination of NS_XRE_ prefixed flags (defined above).
*/
PRUint32 flags;
};
/**
* The contract id for the nsIXULAppInfo service.
*/
@ -130,19 +152,25 @@ struct nsXREAppData
/**
* Begin an XUL application. Does not return until the user exits the
* application.
* @param aAppData Information about the application being run.
*
* @param argc/argv Command-line parameters to pass to the application. These
* are in the "native" character set.
*
* @param aAppData Information about the application to be run.
*
* @return A native result code suitable for returning from main().
*
* @note If the binary is linked against the standalone XPCOM glue,
* XPCOMGlueStartup() should be called before this method.
*
* @note XXXbsmedberg Nobody uses the glue yet, but there is a
* potentital problem: on windows, the glue calls
* potential problem: on windows, the standalone glue calls
* SetCurrentDirectory, and relative paths on the command line
* won't be correct.
*/
extern "C" XULAPI int
XRE_main(int argc, char* argv[], const nsXREAppData* aAppData);
XRE_main(int argc, char* argv[],
const nsXREAppData* aAppData);
/**
* Given a path relative to the current working directory (or an absolute

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

@ -109,28 +109,6 @@ nsFastLoadService::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
return rv;
}
#if defined XP_MAC
// Mac format: "<Basename> FastLoad File" with <basename> capitalized.
# include "nsCRT.h"
# define MASSAGE_BASENAME(bn) (bn.SetCharAt(nsCRT::ToUpper(bn.CharAt(0)), 0))
# define PLATFORM_FASL_SUFFIX " FastLoad File"
#elif defined(XP_UNIX) || defined(XP_BEOS)
// Unix format: "<basename>.mfasl".
# define MASSAGE_BASENAME(bn) /* nothing */
# define PLATFORM_FASL_SUFFIX ".mfasl"
#elif defined(XP_WIN) || defined(XP_OS2)
// Windows format: "<basename>.mfl".
# define MASSAGE_BASENAME(bn) /* nothing */
# define PLATFORM_FASL_SUFFIX ".mfl"
#endif
nsresult
nsFastLoadService::NewFastLoadFile(const char* aBaseName, nsIFile* *aResult)
{
@ -154,7 +132,6 @@ nsFastLoadService::NewFastLoadFile(const char* aBaseName, nsIFile* *aResult)
return rv;
nsCAutoString name(aBaseName);
MASSAGE_BASENAME(name);
name += PLATFORM_FASL_SUFFIX;
rv = file->AppendNative(name);
if (NS_FAILED(rv))

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

@ -152,4 +152,10 @@ NS_AddFastLoadDependency(nsIFile* aFile)
return NS_OK;
}
#if defined(XP_UNIX) || defined(XP_BEOS)
#define PLATFORM_FASL_SUFFIX ".mfasl"
#elif defined(XP_WIN) || defined(XP_OS2)
#define PLATFORM_FASL_SUFFIX ".mfl"
#endif
%}

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

@ -19,6 +19,7 @@
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
* Benjamin Smedberg <benjamin@smedbergs.us>
*
* 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
@ -135,22 +136,25 @@ static PRBool CheckMaxVersion(const char *versionStr)
/**
* Parse application data.
*/
static const nsXREAppData* LoadAppData(const char* appDataFile)
static int LoadAppData(const char* appDataFile, nsXREAppData* aResult)
{
static char vendor[256], name[256], version[32], buildID[32], copyright[512];
static nsXREAppData data = {
vendor, name, version, buildID, {0,0,0,{0,0,0,0,0,0,0,0}}, copyright, 0 };
static char vendor[256], name[256], version[32], buildID[32], appID[256], copyright[512];
nsresult rv;
nsCOMPtr<nsILocalFile> lf;
XRE_GetFileFromPath(appDataFile, getter_AddRefs(lf));
if (!lf)
return nsnull;
return 2;
nsINIParser parser;
if (NS_FAILED(parser.Init(lf)))
return nsnull;
nsresult rv;
rv = lf->GetParent(&aResult->appDir);
if (NS_FAILED(rv))
return 2;
nsINIParser parser;
rv = parser.Init(lf)
if (NS_FAILED(rv))
return 2;
// Gecko version checking
//
@ -161,50 +165,42 @@ static const nsXREAppData* LoadAppData(const char* appDataFile)
rv = parser.GetString("Gecko", "MinVersion", gkVersion, sizeof(gkVersion));
if (NS_FAILED(rv) || !CheckMinVersion(gkVersion)) {
Output(PR_TRUE, "Error: Gecko MinVersion requirement not met.\n");
return nsnull;
return 1;
}
rv = parser.GetString("Gecko", "MaxVersion", gkVersion, sizeof(gkVersion));
if (NS_SUCCEEDED(rv) && !CheckMaxVersion(gkVersion)) {
Output(PR_TRUE, "Error: Gecko MaxVersion requirement not met.\n");
return nsnull;
}
// Read the app ID, if specified
char id[38] = "";
rv = parser.GetString("App", "ID", id, sizeof(id));
if (NS_SUCCEEDED(rv)) {
if(!data.id.Parse(id)) {
memset(&data.id, 0, sizeof(data.id));
}
return 1;
}
PRUint32 i;
// Read string-valued fields
const struct {
const char* key;
char* buf;
size_t bufLen;
PRBool required;
const char *key;
char **fill;
char *buf;
size_t bufLen;
PRBool required;
} string_fields[] = {
{ "Vendor", vendor, sizeof(vendor), PR_FALSE },
{ "Name", name, sizeof(name), PR_TRUE },
{ "Version", version, sizeof(version), PR_FALSE },
{ "BuildID", buildID, sizeof(buildID), PR_TRUE },
{ "Copyright", copyright, sizeof(copyright), PR_FALSE }
{ "Vendor", &aResult->vendor, vendor, sizeof(vendor), PR_FALSE },
{ "Name", &aResult->name, name, sizeof(name), PR_TRUE },
{ "Version", &aResult->version, version, sizeof(version), PR_FALSE },
{ "BuildID", &aResult->buildID, buildID, sizeof(buildID), PR_TRUE },
{ "ID", &aResult->ID, appID, sizeof(appID), PR_FALSE },
{ "Copyright", &aResult->copyright, copyright, sizeof(copyright), PR_FALSE }
};
for (i = 0; i < NS_ARRAY_LENGTH(string_fields); ++i) {
rv = parser.GetString("App", string_fields[i].key, string_fields[i].buf,
string_fields[i].bufLen);
if (NS_FAILED(rv)) {
if (string_fields[i].required) {
Output(PR_TRUE, "Error: %x: No \"%s\" field.\n",
rv, string_fields[i].key);
return nsnull;
} else {
string_fields[i].buf[0] = '\0';
}
if (NS_SUCCEEDED(rv)) {
*fill = string_fields[i].buf;
}
else if (string_fields[i].required) {
Output(PR_TRUE, "Error: %x: No \"%s\" field.\n",
rv, string_fields[i].key);
return 1;
}
}
@ -217,7 +213,7 @@ static const nsXREAppData* LoadAppData(const char* appDataFile)
{ "EnableExtensionManager", NS_XRE_ENABLE_EXTENSION_MANAGER }
};
char buf[6]; // large enough to hold "false"
data.flags = 0;
aResult->flags = 0;
for (i = 0; i < NS_ARRAY_LENGTH(boolean_fields); ++i) {
rv = parser.GetString("XRE", boolean_fields[i].key, buf, sizeof(buf));
// accept a truncated result since we are only interested in the
@ -225,22 +221,22 @@ static const nsXREAppData* LoadAppData(const char* appDataFile)
// expanding these boolean attributes to express additional options.
if ((NS_SUCCEEDED(rv) || rv == NS_ERROR_LOSS_OF_SIGNIFICANT_DATA) &&
(buf[0] == '1' || buf[0] == 't' || buf[0] == 'T')) {
data.flags |= boolean_fields[i].flag;
aResult->flags |= boolean_fields[i].flag;
}
}
#ifdef DEBUG
printf("---------------------------------------------------------\n");
printf(" Vendor %s\n", data.appVendor);
printf(" Name %s\n", data.appName);
printf(" Version %s\n", data.appVersion);
printf(" BuildID %s\n", data.appBuildID);
printf(" Copyright %s\n", data.copyright);
printf(" Flags %08x\n", data.flags);
printf(" Vendor %s\n", aResult->appVendor);
printf(" Name %s\n", aResult->appName);
printf(" Version %s\n", aResult->appVersion);
printf(" BuildID %s\n", aResult->appBuildID);
printf(" Copyright %s\n", aResult->copyright);
printf(" Flags %08x\n", aResult->flags);
printf("---------------------------------------------------------\n");
#endif
return &data;
return 0;
}
int main(int argc, char* argv[])
@ -278,7 +274,6 @@ int main(int argc, char* argv[])
geckoVersion = ParseVersion(GRE_BUILD_ID);
PRBool hasAppOption;
const char *appDataFile;
if (IsArg(argv[1], "app"))
{
@ -287,40 +282,24 @@ int main(int argc, char* argv[])
Output(PR_TRUE, "Error: APP-FILE must be specified!\n");
return 1;
}
hasAppOption = PR_TRUE;
appDataFile = argv[2];
argv += 2;
argc -= 2;
}
else
{
hasAppOption = PR_FALSE;
appDataFile = argv[1];
argv += 1;
argc -= 1;
}
const nsXREAppData *appData = LoadAppData(appDataFile);
if (!appData)
{
Output(PR_TRUE, "Error: Invalid or missing application data!\n");
return 1;
}
nsXREAppData appData = { sizeof(nsXREAppData), 0 };
char **argv2 = NULL;
if (!hasAppOption)
{
// fixup argv to start with -app.
argv2 = (char **) malloc(sizeof(char*) * (argc + 2));
argv2[0] = argv[0];
argv2[1] = "-app";
for (int i=1; i<argc; ++i)
argv2[i+1] = argv[i];
argv2[argc+1] = NULL;
argv = argv2;
argc++;
}
int rv = LoadAppData(appDataFile, &appData);
if (!rv)
rv = XRE_main(argc, argv, appData);
int rv = XRE_main(argc, argv, appData);
if (argv2)
free(argv2);
NS_IF_RELEASE(appData.appDir);
return rv;
}