170006 - better organization for update checking, create new updates component and background update service, new unified UI.

This commit is contained in:
ben%bengoodger.com 2004-04-22 06:28:22 +00:00
Родитель 086b57ea5b
Коммит f1c1c327a9
19 изменённых файлов: 1096 добавлений и 187 удалений

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

@ -42,7 +42,7 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = downloads extensions xpinstall
DIRS = downloads extensions update xpinstall
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
# XXXben this is temporary, until Thunderbird is converted to Pinstripe on MacOS X. For now,

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

@ -57,7 +57,7 @@ function Startup()
gWindowState = window.arguments[0];
gExtensionsView = document.getElementById("extensionsView");
gExtensionManager = Components.classes["@mozilla.org/extension-manager;1"]
gExtensionManager = Components.classes["@mozilla.org/extensions/manager;1"]
.getService(Components.interfaces.nsIExtensionManager);
// Extension Command Updating is handled by a command controller.
@ -365,9 +365,39 @@ var gExtensionsViewController = {
cmd_update: function ()
{
openDialog("chrome://mozapps/content/extensions/update.xul", "", "chrome,modal",
gWindowState, gExtensionManager,
gExtensionsView.selected ? stripPrefix(gExtensionsView.selected.id) : null);
var items = this._getItemList(null);
gExtensionManager.update(items, item.length, false);
},
_getItemList: function (aItemID)
{
var items = [];
if (aItemID) {
var item = Components.classes["@mozilla.org/extensions/item;1"]
.createInstance(Components.interfaces.nsIExtensionItem);
item.init(aItemID, this.getExtensionProperty(aItemID, "version"),
this.getExtensionProperty(aItemID, "name"),
-1, "", Components.interfaces.nsIExtensionItem.TYPE_EXTENSION); // XXXben
items.push(item);
}
else {
var ctr = Components.classes["@mozilla.org/rdf/container;1"]
.createInstance(Components.interfaces.nsIRDFContainer);
ctr.Init(this, this._rdf.GetResource("urn:mozilla:extension:root"));
var elements = ctr.GetElements();
while (elements.hasMoreElements()) {
var e = elements.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
var id = this._stripPrefix(e.Value);
var item = Components.classes["@mozilla.org/extensions/item;1"]
.createInstance(Components.interfaces.nsIExtensionItem);
item.init(id, this.getExtensionProperty(id, "version"),
this.getExtensionProperty(id, "name"),
-1, "", Components.interfaces.nsIExtensionItem.TYPE_EXTENSION); // XXXben
items.push(item);
}
}
return items;
},
cmd_uninstall: function ()

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

@ -34,7 +34,7 @@ var gMismatchDialog = {
accept: function ()
{
var em = Components.classes["@mozilla.org/extension-manager;1"]
var em = Components.classes["@mozilla.org/extensions/manager;1"]
.getService(Components.interfaces.nsIExtensionManager);
openDialog("chrome://mozapps/content/extensions/update.xul",
"", "chrome,modal", "extensions", em, null);

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

@ -17,4 +17,4 @@ statusConnectionFailed=Connection to %S failed, skipping...
progress=(%S of %S items complete)
mismatchCheckNow=Check Now
mismatchDontCheck=Dont Check
mismatchDontCheck=Don't Check

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

@ -40,6 +40,28 @@
interface nsIInputStream;
interface nsIRDFDataSource;
interface nsIVariant;
[scriptable, uuid(37648f86-0f77-4007-929e-673a75d5438f)]
interface nsIExtensionItem : nsISupports
{
readonly attribute string id;
readonly attribute string version;
readonly attribute wstring name;
readonly attribute long row;
readonly attribute wstring xpiURL;
const unsigned short TYPE_EXTENSION = 0x01;
const unsigned short TYPE_THEME = 0x02;
const unsigned short TYPE_LOCALE = 0x04;
readonly attribute long type;
void init(in string aID, in string aVersion, in wstring aName,
in long aRow, in wstring aXPIURL, in long aType);
nsIVariant toObject();
};
[scriptable, uuid(c3515b0f-99f4-453b-805e-1fdf5724d6d9)]
interface nsIExtensionManager : nsISupports
@ -48,11 +70,13 @@ interface nsIExtensionManager : nsISupports
void uninstallExtension(in string aExtensionID);
void enableExtension(in string aExtensionID);
void disableExtension(in string aExtensionID);
void updateExtension(in string aExtensionID);
void installTheme(in string aThemeID);
void uninstallTheme(in string aThemeID);
void updateTheme(in string aThemeID);
void update([array, size_is(aItemCount)] in nsIExtensionItem aItems,
in unsigned long aItemCount,
in boolean aShowUI);
readonly attribute nsIRDFDataSource datasource;
};

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

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

@ -0,0 +1,90 @@
package org.mozilla.update.extensions;
public class ExtensionItem
{
private int row;
private java.lang.String id;
private java.lang.String version;
private java.lang.String name;
private java.lang.String xpiURL;
private int type;
public ExtensionItem()
{
}
public int getRow()
{
return row;
}
public void setRow(int row)
{
this.row = row;
}
public java.lang.String getId()
{
return id;
}
public void setId(java.lang.String id)
{
this.id = id;
}
public java.lang.String getVersion()
{
return version;
}
public void setVersion(java.lang.String version)
{
this.version = version;
}
public java.lang.String getName()
{
return name;
}
public void setName(java.lang.String name)
{
this.name = name;
}
public java.lang.String getXpiURL()
{
return xpiURL;
}
public void setXpiURL(java.lang.String xpiURL)
{
this.xpiURL = xpiURL;
}
public int getType()
{
return type;
}
public void setType(int type)
{
this.type = type;
}
}
//public class ExtensionType
//{
// public ExtensionType()
// {
// }
//
// public int row;
// public String id;
// public String version;
// public String name;
// public String xpiURL;
// public int type;
//}

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

@ -56,12 +56,12 @@ public class VersionCheck
}
*/
public Extension[] getExtensionsToUpdate(Extension[] aExtensions, String aTargetApp, String aTargetAppVersion)
public ExtensionItem[] getExtensionsToUpdate(ExtensionItem[] aExtensions, String aTargetApp, String aTargetAppVersion)
{
Vector results = new Vector();
for (int i = 0; i < aExtensions.length; ++i)
{
Extension e = aExtensions[i];
ExtensionItem e = aExtensions[i];
int row = getNewestExtension(e.getId(), e.getVersion(), aTargetApp, aTargetAppVersion);
if (row != -1)
{
@ -74,16 +74,16 @@ public class VersionCheck
}
}
return (Extension[])results.toArray();
return (ExtensionItem[])results.toArray();
}
// This method is a temporary workaround until Mozilla's Web Services implementation
// supports passing Arrays of complex types.
public Extension getNewestExtension(Extension aExtension,
String aTargetApp,
String aTargetAppVersion)
public ExtensionItem getNewestExtension(ExtensionItem aExtension,
String aTargetApp,
String aTargetAppVersion)
{
Extension e = new Extension();
ExtensionItem e = new ExtensionItem();
int row = getNewestExtension(aExtension.getId(), aExtension.getVersion(),
aTargetApp, aTargetAppVersion);

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

@ -44,15 +44,45 @@ const PREF_UPDATE_EXTENSIONS = "update.extensions.enabled";
const PREF_UPDATE_AUTOUPDATE = "update.extensions.autoUpdate";
const PREF_UPDATE_APP = "update.app.enabled";
function Extension (aID, aVersion, aName, aRow, aXPIURL)
function ExtensionItem ()
{
this.id = aID;
this.version = aVersion;
this.name = aName;
this.row = aRow;
this.xpiURL = aXPIURL;
}
ExtensionItem.prototype = {
init: function (aID, aVersion, aName, aRow, aXPIURL, aType)
{
this._id = aID;
this._version = aVersion;
this._name = aName;
this._row = aRow;
this._xpiURL = aXPIURL;
this._type = aType;
},
get id() { return this._id; },
get version() { return this._version; },
get name() { return this._name; },
get row() { return this._row; },
get xpiURL() { return this._xpiURL; },
get type() { return this._type; },
toObject: function ()
{
return { id: this._id, version: this._version, name: this._name,
row: this._row, xpiURL: this._xpiURL, type: this._type };
},
/////////////////////////////////////////////////////////////////////////////
// nsISupports
QueryInterface: function (aIID)
{
if (!aIID.equals(Components.interfaces.nsIExtensionItem) &&
!aIID.equals(Components.interfaces.nsISupports))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
};
function VersionChecker(aExtensionResource, aAppID, aAppVersion, aDataSource)
{
this._extensionResource = aExtensionResource;
@ -157,23 +187,20 @@ nsExtensionManager.prototype = {
// doesn't happen all that often.
this._ensureDS();
var currAppID = pref.getCharPref(PREF_EM_APP_ID);
var extensions = this._ds.getIncompatibleExtensionList(currAppID, currAppVersion);
var items = this._ds.getIncompatibleItemList(currAppID, currAppVersion);
if (extensions.length > 0) {
if (items.length > 0) {
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher);
var ary = Components.classes["@mozilla.org/supports-array;1"]
.createInstance(Components.interfaces.nsISupportsArray);
for (var i = 0; i < extensions.length; ++i) {
var str = Components.classes["@mozilla.org/supports-string;1"]
.createInstance(Components.interfaces.nsISupportsString);
str.data = extensions[i].toSource();
ary.AppendElement(str);
for (var i = 0; i < items.length; ++i) {
ary.AppendElement(items[i]);
// Now disable the extension so it won't hurt anything.
this.disableExtension(extensions[i].id);
this.disableExtension(items[i].id);
}
ww.openWindow(null, "chrome://mozapps/content/extensions/mismatch.xul",
ww.openWindow(null, "chrome://mozapps/content/update/update.xul",
"", "chrome,centerscreen,modal", ary);
//
}
@ -181,7 +208,7 @@ nsExtensionManager.prototype = {
// Now update the last app version so we don't do this checking
// again.
pref.setCharPref(PREF_EM_LAST_APP_VERSION, currAppVersion);
// pref.setCharPref(PREF_EM_LAST_APP_VERSION, currAppVersion);
}
},
@ -224,20 +251,16 @@ nsExtensionManager.prototype = {
this._ds.disableExtension(aExtensionID);
},
updateExtension: function (aExtensionID)
update: function (aItems, aItemCount, aShowUI)
{
var pref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
var appID = pref.getCharPref(PREF_EM_APP_ID);
var appVersion = pref.getCharPref(PREF_EM_APP_VERSION);
var extensions = this._ds.getExtensionList(aExtensionID);
// var updater = new nsExtensionUpdater2(extensions, appID, appVersion);
// updater.loadSchema();
var updater = new nsExtensionUpdater(extensions, appID, appVersion);
var updater = new nsItemUpdater(aItems, appID, appVersion);
updater.checkForUpdates();
},
},
// Themes
installTheme: function (aThemeID)
@ -250,11 +273,6 @@ nsExtensionManager.prototype = {
},
updateTheme: function (aThemeID)
{
},
get datasource()
{
this._ensureDS();
@ -288,11 +306,10 @@ nsExtensionManager.prototype = {
}
};
function nsExtensionUpdater(aExtensions,
aTargetAppID, aTargetAppVersion)
function nsItemUpdater(aItems, aTargetAppID, aTargetAppVersion)
{
this._extensions = aExtensions;
this._count = aExtensions.length;
this._items = aItems;
this._count = aItems.length;
this._appID = aTargetAppID;
this._appVersion = aTargetAppVersion;
@ -300,7 +317,7 @@ function nsExtensionUpdater(aExtensions,
.getService(Components.interfaces.nsIObserverService);
}
nsExtensionUpdater.prototype = {
nsItemUpdater.prototype = {
/////////////////////////////////////////////////////////////////////////////
//
checkForUpdates: function ()
@ -316,8 +333,8 @@ nsExtensionUpdater.prototype = {
_checkForUpdates: function ()
{
for (var i = 0; i < this._extensions.length; ++i) {
var e = this._extensions[i];
for (var i = 0; i < this._items.length; ++i) {
var e = this._items[i];
this._os.notifyObservers(null, "update-item-started", e.name + " " + e.version);
this._proxy.getNewestExtension(e, this._appID, this._appVersion);
}
@ -339,12 +356,12 @@ nsExtensionUpdater.prototype = {
getNewestExtensionCallback: function (aResult)
{
var extension = aResult;
var item = aResult;
try {
extension.name.toString(); // XXXben This is a lame hack to cause an exception to be
// thrown for null values when there is no newer extension
// or something else bad happens on the server that we
// don't recognize.
item.name.toString(); // XXXben This is a lame hack to cause an exception to be
// thrown for null values when there is no newer extension
// or something else bad happens on the server that we
// don't recognize.
this._os.notifyObservers(aResult, "update-item-ended", "goat");
}
catch (e) {
@ -385,36 +402,9 @@ nsExtensionsDataSource.prototype = {
return aResourceURI.substr("urn:mozilla:extension:".length, aResourceURI.length);
},
getExtensionList: function (aExtensionID)
getIncompatibleItemList: function (aAppID, aAppVersion)
{
var extensions = [];
if (aExtensionID) {
extensions.push(new Extension(aExtensionID,
this.getExtensionProperty(aExtensionID, "version"),
this.getExtensionProperty(aExtensionID, "name"),
-1, ""));
}
else {
var ctr = Components.classes["@mozilla.org/rdf/container;1"]
.createInstance(Components.interfaces.nsIRDFContainer);
ctr.Init(this, this._rdf.GetResource("urn:mozilla:extension:root"));
var elements = ctr.GetElements();
while (elements.hasMoreElements()) {
var e = elements.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
var id = this._stripPrefix(e.Value);
extensions.push(new Extension(id,
this.getExtensionProperty(id, "version"),
this.getExtensionProperty(id, "name"),
-1, ""));
}
}
return extensions;
},
getIncompatibleExtensionList: function (aAppID, aAppVersion)
{
var extensions = [];
var items = [];
var ctr = Components.classes["@mozilla.org/rdf/container;1"]
.createInstance(Components.interfaces.nsIRDFContainer);
@ -426,13 +416,15 @@ nsExtensionsDataSource.prototype = {
var checker = new VersionChecker(e, aAppID, aAppVersion, this);
if (!checker.isCompatible) {
var id = this._stripPrefix(e.Value);
extensions.push(new Extension(id,
this.getExtensionProperty(id, "version"),
this.getExtensionProperty(id, "name"),
-1, ""));
var item = Components.classes["@mozilla.org/extensions/item;1"]
.createInstance(Components.interfaces.nsIExtensionItem);
item.init(id, this.getExtensionProperty(id, "version"),
this.getExtensionProperty(id, "name"),
-1, "", Components.interfaces.nsIExtensionItem.TYPE_EXTENSION);
items.push(item);
}
}
return extensions;
return items;
},
_setProperty: function (aDS, aSource, aProperty, aNewValue)
@ -488,69 +480,6 @@ nsExtensionsDataSource.prototype = {
this._setExtensionProperty(aExtensionID, this._emR("toBeUninstalled"), this._emL("true"));
},
getUpdateURLs: function (aExtensionID)
{
var pref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
var appID = pref.getCharPref(PREF_EM_APP_ID);
var urls = [];
if (aExtensionID) {
var updateURL = this._getUpdateURLInternal(aExtensionID);
updateURL = updateURL.replace(/%APP%/g, escape(appID));
updateURL = updateURL.replace(/%ITEM%/g, escape(aExtensionID));
urls.push(updateURL);
}
else {
var ctr = Components.classes["@mozilla.org/rdf/container;1"]
.createInstance(Components.interfaces.nsIRDFContainer);
ctr.Init(this, this._rdf.GetResource("urn:mozilla:extension:root"));
var urlHash = { };
var e = ctr.GetElements();
while (e.hasMoreElements()) {
var r = e.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
var extensionID = r.Value.substr("urn:mozilla:extension:".length, r.Value.length);
var updateURL = this._getUpdateURLInternal(extensionID);
if (!(updateURL in urlHash))
urlHash[updateURL] = [];
urlHash[updateURL].push(extensionID);
}
for (var url in urlHash) {
var guidString = "";
var urlCount = urlHash[url].length;
for (var i = 0; i < urlCount; ++i)
guidString += escape(urlHash[url][i] + (i < urlCount - 1 ? "," : ""));
url = url.replace(/%APP%/g, appID);
url = url.replace(/%ITEM%/g, guidString);
urls.push(url);
}
}
return urls;
},
_getUpdateURLInternal: function (aExtensionID)
{
var updateURL;
var extension = this._rdf.GetResource("urn:mozilla:extension:" + aExtensionID);
if (this.hasArcOut(extension, this._emR("updateURL"))) {
updateURL = this.GetTarget(extension, this._emR("updateURL"), true);
if (updateURL)
updateURL = updateURL.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
}
if (!updateURL) {
var pref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
updateURL = pref.getCharPref(PREF_EM_DEFAULTUPDATEURL);
}
return updateURL;
},
loadExtensions: function (aProfile)
{
var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
@ -787,48 +716,65 @@ var gModule = {
}
aComponentManager = aComponentManager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
aComponentManager.registerFactoryLocation(this._cid,
"Extension Manager",
this._contractId,
aFileSpec,
aLocation,
aType);
for (var key in this._objects) {
var obj = this._objects[key];
aComponentManager.registerFactoryLocation(obj.CID, obj.className, obj.contractID,
aFileSpec, aLocation, aType);
}
// Make the Extension Manager a startup observer
var categoryManager = Components.classes["@mozilla.org/categorymanager;1"]
.getService(Components.interfaces.nsICategoryManager);
categoryManager.addCategoryEntry("app-startup", "Extension Manager",
"service," + this._contractId, true, true, null);
categoryManager.addCategoryEntry("app-startup", this._objects.manager.className,
"service," + this._objects.manager.contractID,
true, true, null);
},
getClassObject: function (aComponentManager, aCID, aIID)
{
if (!aCID.equals(this._cid))
throw Components.results.NS_ERROR_NO_INTERFACE;
if (!aIID.equals(Components.interfaces.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
return this._factory;
},
_cid: Components.ID("{8A115FAA-7DCB-4e8f-979B-5F53472F51CF}"),
_contractId: "@mozilla.org/extension-manager;1",
_factory: {
createInstance: function (aOuter, aIID)
{
if (aOuter != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
if (!gExtensionManager)
gExtensionManager = new nsExtensionManager();
return gExtensionManager.QueryInterface(aIID);
for (var key in this._objects) {
if (aCID.equals(this._objects[key].CID))
return this._objects[key].factory;
}
throw Components.results.NS_ERROR_NO_INTERFACE;
},
_objects: {
manager: { CID: Components.ID("{8A115FAA-7DCB-4e8f-979B-5F53472F51CF}"),
contractID: "@mozilla.org/extensions/manager;1",
className: "Extension Manager",
factory: {
createInstance: function (aOuter, aIID)
{
if (aOuter != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
if (!gExtensionManager)
gExtensionManager = new nsExtensionManager();
return gExtensionManager.QueryInterface(aIID);
}
}
},
item: { CID: Components.ID("{F3294B1C-89F4-46F8-98A0-44E1EAE92518}"),
contractID: "@mozilla.org/extensions/item;1",
className: "Extension Item",
factory: {
createInstance: function (aOuter, aIID)
{
if (aOuter != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return new ExtensionItem().QueryInterface(aIID);
}
}
}
},
canUnload: function (aComponentManager)
{
return true;

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

@ -106,3 +106,68 @@ nsExtensionUpdater2.prototype = {
};
// this will come back later when we do custom update urls
getUpdateURLs: function (aExtensionID)
{
var pref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
var appID = pref.getCharPref(PREF_EM_APP_ID);
var urls = [];
if (aExtensionID) {
var updateURL = this._getUpdateURLInternal(aExtensionID);
updateURL = updateURL.replace(/%APP%/g, escape(appID));
updateURL = updateURL.replace(/%ITEM%/g, escape(aExtensionID));
urls.push(updateURL);
}
else {
var ctr = Components.classes["@mozilla.org/rdf/container;1"]
.createInstance(Components.interfaces.nsIRDFContainer);
ctr.Init(this, this._rdf.GetResource("urn:mozilla:extension:root"));
var urlHash = { };
var e = ctr.GetElements();
while (e.hasMoreElements()) {
var r = e.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
var extensionID = r.Value.substr("urn:mozilla:extension:".length, r.Value.length);
var updateURL = this._getUpdateURLInternal(extensionID);
if (!(updateURL in urlHash))
urlHash[updateURL] = [];
urlHash[updateURL].push(extensionID);
}
for (var url in urlHash) {
var guidString = "";
var urlCount = urlHash[url].length;
for (var i = 0; i < urlCount; ++i)
guidString += escape(urlHash[url][i] + (i < urlCount - 1 ? "," : ""));
url = url.replace(/%APP%/g, appID);
url = url.replace(/%ITEM%/g, guidString);
urls.push(url);
}
}
return urls;
},
_getUpdateURLInternal: function (aExtensionID)
{
var updateURL;
var extension = this._rdf.GetResource("urn:mozilla:extension:" + aExtensionID);
if (this.hasArcOut(extension, this._emR("updateURL"))) {
updateURL = this.GetTarget(extension, this._emR("updateURL"), true);
if (updateURL)
updateURL = updateURL.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
}
if (!updateURL) {
var pref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
updateURL = pref.getCharPref(PREF_EM_DEFAULTUPDATEURL);
}
return updateURL;
},

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

@ -19,10 +19,8 @@ toolkit.jar:
* content/mozapps/extensions/extensions.css (extensions/content/extensions.css)
* content/mozapps/extensions/about.xul (extensions/content/about.xul)
* content/mozapps/extensions/about.js (extensions/content/about.js)
* content/mozapps/extensions/update.xul (extensions/content/update.xul)
* content/mozapps/extensions/update.js (extensions/content/update.js)
* content/mozapps/extensions/mismatch.xul (extensions/content/mismatch.xul)
* content/mozapps/extensions/mismatch.js (extensions/content/mismatch.js)
* content/mozapps/update/update.xul (update/content/update.xul)
* content/mozapps/update/update.js (update/content/update.js)
* content/mozapps/shared/richview.xml (shared/content/richview.xml)
content/mozapps/contents.rdf (contents-content.rdf)
@ -37,8 +35,7 @@ en-US.jar:
locale/en-US/mozapps/extensions/extensions.dtd (extensions/locale/extensions.dtd)
locale/en-US/mozapps/extensions/extensions.properties (extensions/locale/extensions.properties)
locale/en-US/mozapps/extensions/about.dtd (extensions/locale/about.dtd)
locale/en-US/mozapps/extensions/update.dtd (extensions/locale/update.dtd)
locale/en-US/mozapps/extensions/mismatch.dtd (extensions/locale/mismatch.dtd)
locale/en-US/mozapps/update/update.dtd (update/locale/update.dtd)
locale/en-US/mozapps/contents.rdf (contents-locale.rdf)
classic.jar:

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

@ -0,0 +1,46 @@
# ***** 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 Extension Manager.
#
# 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@mozilla.org>
#
# 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 *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src
include $(topsrcdir)/config/rules.mk

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

@ -0,0 +1,195 @@
//
// window.arguments is an array of nsIExtensionItem implementing objects that
// are to be updated.
// * if the array is empty, all items are updated (like a background update
// check)
// * if the array contains one or two ExtensionItems, with null id fields,
// all items of that /type/ are updated.
//
// This UI can be opened from the following places, and in the following modes:
//
// - from the Version Compatibility Checker at startup
// as the application starts a check is done to see if the application being
// started is the same version that was started last time. If it isn't, a
// list of ExtensionItems that are incompatible with the verison being
// started is generated and this UI opened with that list. This UI then
// offers to check for updates to those ExtensionItems that are compatible
// with the version of the application being started.
//
// In this mode, the wizard is opened to panel 'mismatch'.
//
// - from the Extension Manager or Options Dialog or any UI where the user
// directly requests to check for updates.
// in this case the user selects ExtensionItem(s) to update and this list
// is passed to this UI. If a single item is sent with the id field set to
// null but the type set correctly, this UI will check for updates to all
// items of that type.
//
// In this mode, the wizard is opened to panel 'checking'.
//
// - from the Updates Available Status Bar notification.
// in this case the background update checking has determined there are new
// updates that can be installed and has prepared a list for the user to see.
// They can update by clicking on a status bar icon which passes the list
// to this UI which lets them choose to install updates.
//
// In this mode, the wizard is opened to panel 'updatesFound' if the data
// set is immediately available, or 'checking' if the user closed the browser
// since the last background check was performed and the check needs to be
// performed again.
//
const nsIExtensionItem = Components.interfaces.nsIExtensionItem;
var gExtensionItems = window.arguments;
var gUpdateWizard = {
init: function ()
{
gMismatchPage.init();
},
uninit: function ()
{
gUpdatePage.uninit();
}
};
var gMismatchPage = {
_items: [],
init: function ()
{
for (var i = 0; i < gExtensionItems.length; ++i)
this._items.push(gExtensionItems[i].QueryInterface(Components.interfaces.nsIExtensionItem));
var incompatible = document.getElementById("mismatch.incompatible");
for (var i = 0; i < this._items.length; ++i) {
var item = this._items[i];
var listitem = document.createElement("listitem");
listitem.setAttribute("label", item.name + " " + item.version);
incompatible.appendChild(listitem);
}
var strings = document.getElementById("extensionsStrings");
var next = document.documentElement.getButton("next");
next.label = strings.getString("mismatchCheckNow");
var cancel = document.documentElement.getButton("cancel");
cancel.label = strings.getString("mismatchDontCheck");
},
onPageAdvanced: function ()
{
dump("*** mismatch page advanced\n");
}
};
var gUpdatePage = {
_itemsToUpdate: [],
_messages: ["update-started",
"update-ended",
"update-item-started",
"update-item-ended",
"update-item-error"],
onPageShow: function ()
{
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
for (var i = 0; i < this._messages.length; ++i)
os.addObserver(this, this._messages[i], false);
var extensions = [];
var themes = [];
for (i = 0; i < gExtensionItems.length; ++i) {
switch (gExtensionItems[i].type) {
case nsIExtensionItem.TYPE_EXTENSION:
extensions.push(gExtensionItems[i]);
break;
case nsIExtensionItem.TYPE_THEME:
themes.push(gExtensionItems[i]);
break;
}
}
var em = Components.classes["@mozilla.org/extensions/manager;1"]
.getService(Components.interfaces.nsIExtensionManager);
if (this._updateType == "extensions")
em.updateExtensions(extensions);
else if (gUpdateType == "themes")
em.updateTheme(this._extensionID);
},
uninit: function ()
{
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
for (var i = 0; i < this._messages.length; ++i)
os.removeObserver(this, this._messages[i]);
},
observe: function (aSubject, aTopic, aData)
{
switch (aTopic) {
case "update-started":
break;
case "update-item-started":
break;
case "update-item-ended":
this._extensionsToUpdate.push(aSubject);
break;
case "update-ended":
var installObj = { };
for (var i = 0; i < this._extensionsToUpdate.length; ++i) {
var e = this._extensionsToUpdate[i];
installObj[e.name + " " + e.version] = e.xpiURL;
}
if (InstallTrigger.updateEnabled())
InstallTrigger.install(installObj);
document.documentElement.acceptDialog();
break;
}
}
};
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# 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 Update Service.
#
# 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 *****

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

@ -0,0 +1,118 @@
<?xml version="1.0"?>
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# 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 Update Service.
#
# 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 *****
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE wizard [
<!ENTITY % updateDTD SYSTEM "chrome://mozapps/locale/update/update.dtd">
<!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd">
%updateDTD;
%brandDTD;
]>
<wizard id="migrationWizard"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&updateWizard.title;"
onload="gUpdateWizard.init()"
onunload="gUpdateWizard.uninit()"
style="width: 40em;"
buttons="accept,cancel">
<script type="application/x-javascript" src="chrome://mozapps/content/update/update.js"/>
<stringbundleset id="updateSet">
<stringbundle id="brandStrings" src="chrome://global/locale/brand.properties"/>
<stringbundle id="extensionsStrings" src="chrome://mozapps/locale/extensions/extensions.properties"/>
</stringbundleset>
<wizardpage id="mismatch" pageid="mismatch" next="checkingForUpdates"
label="&mismatch.title;"
onpageadvanced="gMismatchPage.onPageAdvanced();">
<label>&mismatch.intro1.label;</label>
<separator class="thin"/>
<listbox id="mismatch.incompatible" flex="1"/>
<separator class="thin"/>
<label style="font-weight: bold;">&mismatch.intro2.label;</label>
<separator class="thin"/>
<label>&mismatch.intro3.label;</label>
</wizardpage>
<wizardpage id="checkingForUpdates" pageid="checkingForUpdates" next="updatesNotFound"
label="&checking.title;"
onpageshow="gUpdatePage.onPageShow();">
<label>&checking.intro.label;</label>
<progressmeter id="progress"/>
</wizardpage>
<wizardpage id="updatesNotFound" pageid="updatesNotFound" next="finished"
label="&updatesNotFound.title;"
onpageshow="UpdateWizard.onUpdatesNotFoundPageShow();"
onpageadvanced="UpdateWizard.onUpdatesNotFoundPageAdvanced();">
</wizardpage>
<wizardpage id="updatesFound" pageid="updatesFound" next="finished"
label="&updatesFound.title;"
onpageshow="UpdateWizard.onUpdatesFoundPageShow();"
onpageadvanced="UpdateWizard.onUpdatesFoundPageAdvanced();">
</wizardpage>
<wizardpage id="installing" pageid="installing"
label="&installing.title;"
onpageshow="UpdateWizard.onFinishedPageShow();"
onpageadvanced="UpdateWizard.onFinishedPageAdvanced();">
</wizardpage>
<wizardpage id="finished" pageid="finished"
label="&finished.title;"
onpageshow="UpdateWizard.onFinishedPageShow();"
onpageadvanced="UpdateWizard.onFinishedPageAdvanced();">
</wizardpage>
</wizard>

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

@ -0,0 +1,21 @@
<!ENTITY updateWizard.title "&brandShortName; Update">
<!ENTITY mismatch.title "Incompatible Extensions">
<!ENTITY mismatch.intro1.label "The following extensions are not compatible with the new version
of &brandShortName; you have just installed.">
<!ENTITY mismatch.intro2.label "They have been disabled until compatible versions are
installed.">
<!ENTITY mismatch.intro3.label "&brandShortName; can check for and install newer, compatible
versions of these extensions.">
<!ENTITY checking.title "Checking for Updates">
<!ENTITY checking.intro.label "&brandShortName; is now checking for updates to your extensions...">
<!ENTITY updatesNotFound.title "No Updates Found">
<!ENTITY updatesFound.title "Updates Found">
<!ENTITY installing.title "Installing Updates">
<!ENTITY finished.title "Done">

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

@ -0,0 +1,50 @@
# ***** 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 Extension Manager.
#
# 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@mozilla.org>
#
# 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 *****
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = update
XPIDL_MODULE = update
XPIDLSRCS = nsIBackgroundUpdateService.idl
include $(topsrcdir)/config/rules.mk

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

@ -0,0 +1,46 @@
/* -*- Mode: IDL; 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 Extension Manager.
*
* 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 "nsISupports.idl"
[scriptable, uuid(c8a2339e-770a-417d-ab9c-efde1f23ba24)]
interface nsIBackgroundUpdateService : nsISupports
{
void watchForUpdates();
};

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

@ -0,0 +1,34 @@
#
# The contents of this file are subject to the Netscape 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/NPL/
#
# 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 mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = update
EXTRA_COMPONENTS = nsBackgroundUpdateService.js
include $(topsrcdir)/config/rules.mk

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

@ -0,0 +1,247 @@
/* -*- 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 Update Service.
*
* 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 ***** */
const PREF_UPDATE_APP_ENABLED = "update.app.enabled";
const PREF_UPDATE_APP_URI = "update.app.uri";
const PREF_UPDATE_EXTENSIONS_ENABLED = "update.extensions.enabled";
const PREF_UPDATE_EXTENSIONS_AUTOUPDATE = "update.extensions.autoUpdate";
const PREF_UPDATE_INTERVAL = "update.interval";
const PREF_UPDATE_LASTUPDATEDATE = "update.lastUpdateDate";
const PREF_UPDATE_UPDATESAVAILABLE = "update.updatesAvailable";
const PREF_UPDATE_SEVERITY = "update.severity";
const PREF_UPDATE_COUNT = "update.count";
function nsBackgroundUpdateService()
{
}
nsBackgroundUpdateService.prototype = {
_timer: null,
/////////////////////////////////////////////////////////////////////////////
// nsIBackgroundUpdateService
watchForUpdates: function ()
{
// This is called when the app starts, so check to see if the time interval
// expired between now and the last time an automated update was performed.
// now is the same one that was started last time.
var pref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
var appUpdatesEnabled = pref.getBoolPref(PREF_UPDATE_APP_ENABLED);
var extUpdatesEnabled = pref.getBoolPref(PREF_UPDATE_EXTENSIONS_ENABLED);
if (!appUpdatesEnabled && !extUpdatesEnabled)
return;
var interval = pref.getIntPref(PREF_UPDATE_INTERVAL);
var lastUpdateTime = pref.getIntPref(PREF_LASTUPDATEDATE);
var timeSinceLastCheck = Date.UTC() - lastUpdateTime;
if (timeSinceLastCheck > interval)
this._checkNow();
else
this._makeTimer(interval - timeSinceLastCheck);
},
/////////////////////////////////////////////////////////////////////////////
// nsITimerCallback
notify: function (aTimer)
{
this._checkNow();
},
/////////////////////////////////////////////////////////////////////////////
// nsBackgroundUpdateService
_makeTimer: function (aDelay)
{
if (this._timer)
this._timer.cancel();
this._timer = Components.classes["@mozilla.org/timer;1"]
.createInstance(Components.interfaces.nsITimer);
timer.initWithCallback(this, aDelay,
Components.interfaces.nsITimer.TYPE_ONE_SHOT);
},
_checkNow: function ()
{
var pref = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
var appUpdatesEnabled = pref.getBoolPref(PREF_UPDATE_APP_ENABLED);
var extUpdatesEnabled = pref.getBoolPref(PREF_UPDATE_EXTENSIONS_ENABLED);
if (appUpdatesEnabled) {
var dsURI = pref.getComplexValue(PREF_UPDATE_APP_URI,
Components.interfaces.nsIPrefLocalizedString).data;
var rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"]
.getService(Components.interfaces.nsIRDFService);
var ds = rdf.GetDataSource(dsURI);
ds = ds.QueryInterface(Components.interfaces.nsIRDFXMLSink);
ds.addXMLSinkObserver(new nsAppUpdateXMLRDFDSObserver());
}
if (extUpdatesEnabled) {
var em = Components.classes["@mozilla.org/extensions/manager;1"]
.getService(Components.interfaces.nsIExtensionManager);
em.update([], 0);
}
this._makeTimer(pref.getIntPref(PREF_UPDATE_INTERVAL));
},
/////////////////////////////////////////////////////////////////////////////
// nsISupports
QueryInterface: function (aIID)
{
if (!aIID.equals(Components.interfaces.nsIBackgroundUpdateService) &&
!aIID.equals(Components.interfaces.nsISupports))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
};
function nsAppUpdateXMLRDFDSObserver()
{
}
nsAppUpdateXMLRDFDSObserver.prototype =
{
/////////////////////////////////////////////////////////////////////////////
// nsIRDFXMLSinkObserver
onBeginLoad: function(aSink)
{
},
onInterrupt: function(aSink)
{
},
onResume: function(aSink)
{
},
onEndLoad: function(aSink)
{
aSink.removeXMLSinkObserver(this);
var ds = aSink.QueryInterface(Components.interfaces.nsIRDFDataSource);
// do update checking here, parsing something like this format:
/*
<?xml version="1.0"?>
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:NC="http://home.netscape.com/NC-rdf#">
<RDF:Description about="urn:updates:latest">
<NC:registryName>Browser</NC:registryName>
<NC:version>1.0.0.0</NC:version>
<NC:URL>http://home.netscape.com/computing/download/index.html</NC:URL>
<NC:productName>Mozilla</NC:productName>
</RDF:Description>
</RDF:RDF>
*/
},
onError: function(aSink, aStatus, aErrorMsg)
{
aSink.removeXMLSinkObserver(this);
}
}
var gBackgroundUpdateService = null;
var gModule = {
_firstTime: true,
registerSelf: function (aComponentManager, aFileSpec, aLocation, aType)
{
if (this._firstTime) {
this._firstTime = false;
throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
}
aComponentManager = aComponentManager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
for (var key in this._objects) {
var obj = this._objects[key];
aComponentManager.registerFactoryLocation(obj.CID, obj.className, obj.contractID,
aFileSpec, aLocation, aType);
}
},
getClassObject: function (aComponentManager, aCID, aIID)
{
if (!aIID.equals(Components.interfaces.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
for (var key in this._objects) {
if (aCID.equals(this._objects[key].CID))
return this._objects[key].factory;
}
throw Components.results.NS_ERROR_NO_INTERFACE;
},
_objects: {
manager: { CID: Components.ID("{8A115FAA-7DCB-4e8f-979B-5F53472F51CF}"),
contractID: "@mozilla.org/updates/background-update-service;1",
className: "Background Update Service",
factory: {
createInstance: function (aOuter, aIID)
{
if (aOuter != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
if (!gUpdateService)
gUpdateService = new nsBackgroundUpdateService();
return gUpdateService.QueryInterface(aIID);
}
}
},
},
canUnload: function (aComponentManager)
{
return true;
}
};
function NSGetModule(compMgr, fileSpec)
{
return gModule;
}