home *** CD-ROM | disk | FTP | other *** search
Text File | 2005-07-29 | 72.0 KB | 1,942 lines |
- /* -*- 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_APP_ID = "app.id";
- const PREF_APP_VERSION = "app.version";
- const PREF_SAFETYNET_VERSION = "safetynet.version";
- const PREF_UPDATE_APP_ENABLED = "app.update.enabled";
- const PREF_UPDATE_APP_AUTOUPDATEENABLED = "app.update.autoUpdateEnabled";
- const PREF_UPDATE_APP_URI = "app.update.url";
- const PREF_UPDATE_APP_UPDATESAVAILABLE = "app.update.updatesAvailable";
- const PREF_UPDATE_APP_INTERVAL = "app.update.interval";
- const PREF_UPDATE_APP_LASTUPDATEDATE = "app.update.lastUpdateDate";
- const PREF_UPDATE_APP_PERFORMED = "app.update.performed";
-
- // MERC BILL - NEW OPTIONS
- const PREF_UPDATE_APP_AUTOINSTALL = "update.autoInstallUpdates";
- const PREF_UPDATE_EXTENSIONS_AUTOINSTALL = "update.autoDownloadInstallUpdatesToExtension";
-
- //const PREF_UPDATE_NOTIFYDOWNLOADED_UPDATES = "update.notifyOfDownloadedUpdates";
- //const PREF_UPDATE_NOTIFYAVAILABLE_UPDATES = "update.notifyOfAvailableUpdates";
- // END MERC
-
- const PREF_UPDATE_EXTENSIONS_ENABLED = "extensions.update.enabled";
- const PREF_UPDATE_EXTENSIONS_AUTOUPDATEENABLED = "extensions.update.autoUpdateEnabled";
- const PREF_UPDATE_EXTENSIONS_AUTOUPDATE = "extensions.update.autoUpdate";
- const PREF_UPDATE_EXTENSIONS_COUNT = "extensions.update.count";
- const PREF_UPDATE_EXTENSIONS_INTERVAL = "extensions.update.interval";
- const PREF_UPDATE_EXTENSIONS_LASTUPDATEDATE = "extensions.update.lastUpdateDate";
- const PREF_UPDATE_EXTENSIONS_SEVERITY_THRESHOLD = "extensions.update.severity.threshold";
-
- const PREF_UPDATE_INTERVAL = "update.interval";
- const PREF_UPDATE_SEVERITY = "update.severity";
- const PREF_UPDATE_SHOW_SLIDING_NOTIFICATION = "update.showSlidingNotification";
-
- const PREF_SILENT_UPDATE_ENABLED = "silent.update.enabled";
- const PREF_SILENT_UPDATE_INTERVAL = "silent.update.interval";
- const PREF_SILENT_UPDATE_LASTUPDATEDATE = "silent.update.lastUpdateDate";
-
- const nsIExtensionManager = Components.interfaces.nsIExtensionManager;
- const nsIUpdateService = Components.interfaces.nsIUpdateService;
- const nsIUpdateItem = Components.interfaces.nsIUpdateItem;
-
- const UPDATED_EXTENSIONS = 0x01;
- const UPDATED_APP = 0x02;
- const UPDATED_SILENT = 0x04;
-
- function APP_NS(aProperty)
- {
- return "http://www.mozilla.org/2004/app-rdf#" + aProperty;
- }
-
- function SILENT_NS(aProperty)
- {
- return "http://www.mozilla.org/2004/silent-rdf#" + aProperty;
- }
-
- function getOSKey()
- {
- return "windows";
- }
-
- function stackTraceFunctionFormat(aFunctionName)
- {
- var classDelimiter = aFunctionName.indexOf("_");
- var className = aFunctionName.substr(0, classDelimiter);
- if (!className)
- className == "<global>";
- var functionName = aFunctionName.substr(classDelimiter + 1, aFunctionName.length);
- if (!functionName)
- functionName == "<anonymous>";
- return className + "::" + functionName;
- }
-
- function stackTrace(aArguments, aMaxCount)
- {
- dump("=[STACKTRACE]=====================================================\n");
- dump("*** at: " + stackTraceFunctionFormat(aArguments.callee.name) + "()\n");
- var temp = aArguments.callee.caller;
- var count = 0;
- while (temp) {
- dump("*** " + stackTraceFunctionFormat(temp.name) + ")\n");
- temp = temp.arguments.callee.caller;
- if (aMaxCount > 0 && ++count == aMaxCount)
- break;
- }
- dump("==================================================================\n");
- }
-
- var gPref = null;
- var gOS = null;
- var gRDF = null;
- var gSiteControls = null;
-
- function nsUpdateService()
- {
- //dump("\n\n**** Starting update service...\n\n");
- gPref = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
- gOS = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- gRDF = Components.classes["@mozilla.org/rdf/rdf-service;1"]
- .getService(Components.interfaces.nsIRDFService);
- gSiteControls = Components.classes["@mozilla.org/browser/sitecontrols-service;1"]
- .getService(Components.interfaces.nsISiteControlsService);
-
- this.watchForUpdates();
-
- var pbi = gPref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
- pbi.addObserver(PREF_UPDATE_APP_AUTOUPDATEENABLED, this, false);
- pbi.addObserver(PREF_UPDATE_APP_ENABLED, this, false);
- pbi.addObserver(PREF_UPDATE_EXTENSIONS_AUTOUPDATEENABLED, this, false);
- pbi.addObserver(PREF_UPDATE_EXTENSIONS_ENABLED, this, false);
- pbi.addObserver(PREF_UPDATE_INTERVAL, this, false);
- pbi.addObserver(PREF_UPDATE_APP_INTERVAL, this, false);
- pbi.addObserver(PREF_UPDATE_EXTENSIONS_INTERVAL, this, false);
- pbi.addObserver(PREF_SILENT_UPDATE_INTERVAL, this, false);
-
- // MERC BILL
- pbi.addObserver(PREF_UPDATE_APP_AUTOINSTALL, this, false);
- pbi.addObserver(PREF_UPDATE_EXTENSIONS_AUTOINSTALL, this, false);
-
- // Observe xpcom-shutdown to unhook pref branch observers above to avoid
- // shutdown leaks.
- gOS.addObserver(this, "xpcom-shutdown", false);
-
- // Reset update state from previous session if an app update was installed.
- if (gPref.prefHasUserValue(PREF_UPDATE_APP_PERFORMED))
- gPref.clearUserPref(PREF_UPDATE_APP_PERFORMED);
- }
-
- // MERC BILL (ADDED _appAutoInstallEnabled)
- nsUpdateService.prototype = {
- _updateObserver: null,
- _appAutoUpdateEnabled: true,
- _extAutoUpdateEnabled: true,
- _silentAutoUpdateEnabled: true,
- // _appAutoInstallEnabled: false, JMC: Goes in the observer
- // _extensionsAutoInstallEnabled: false,
-
- /////////////////////////////////////////////////////////////////////////////
- // nsIUpdateService
- watchForUpdates: function nsUpdateService_watchForUpdates ()
- {
- http://lxr.mozilla.org/aviarybranch/source/toolkit/mozapps/update/src/nsUpdateService.js.in#253
- //dump("\n\n**** calling Watch for Updates...\n\n");
- // 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.
- this._appAutoUpdateEnabled = gPref.getBoolPref(PREF_UPDATE_APP_AUTOUPDATEENABLED);
- this._extAutoUpdateEnabled = gPref.getBoolPref(PREF_UPDATE_EXTENSIONS_AUTOUPDATEENABLED);
- this._silentAutoUpdateEnabled = gPref.getBoolPref(PREF_SILENT_UPDATE_ENABLED);
-
- if (!this._appAutoUpdateEnabled && !this._extAutoUpdateEnabled
- && !this._silentAutoUpdateEnabled)
- return;
-
- this._makeTimer(gPref.getIntPref(PREF_UPDATE_INTERVAL));
- this.checkForUpdatesInternal([], 0, nsIUpdateItem.TYPE_SILENT,
- nsIUpdateService.SOURCE_EVENT_BACKGROUND);
- },
-
- _getAllowedTypes: function nsUpdateService__getAllowedTypes(aRequestedTypes)
- {
- // Figure out what types we're allowed to update. These options
- // differ from PREF_UPDATE_*_AUTOUPDATEENABLED since they effectively
- // shut down the update UI if the administrator/distributor has configured
- // a build to have disallowed these types of update.
- var extUpdateEnabled = gPref.getBoolPref(PREF_UPDATE_EXTENSIONS_ENABLED);
- var appUpdateEnabled = gPref.getBoolPref(PREF_UPDATE_APP_ENABLED);
- var silentUpdateEnabled = gPref.getBoolPref(PREF_SILENT_UPDATE_ENABLED);
-
- var types = 0;
- if (extUpdateEnabled) {
- if (aRequestedTypes & nsIUpdateItem.TYPE_EXTENSION)
- types |= nsIUpdateItem.TYPE_EXTENSION;
- if (aRequestedTypes & nsIUpdateItem.TYPE_THEME)
- types |= nsIUpdateItem.TYPE_THEME;
- }
- if (appUpdateEnabled &&
- (aRequestedTypes & nsIUpdateItem.TYPE_APP))
- types |= nsIUpdateItem.TYPE_APP;
-
- if (silentUpdateEnabled &&
- (aRequestedTypes & nsIUpdateItem.TYPE_SILENT))
- types |= nsIUpdateItem.TYPE_SILENT;
- return types;
- },
-
- checkForUpdates: function nsUpdateService_checkForUpdates (aItems, aItemCount, aUpdateTypes, aSourceEvent, aParentWindow)
- {
- //dump("\n\n**** Checking for updates service...\n\n");
- var types = this._getAllowedTypes(aUpdateTypes);
-
- // Nothing to update
- if (!types) {
- var sbs = Components.classes["@mozilla.org/intl/stringbundle;1"]
- .getService(Components.interfaces.nsIStringBundleService);
- var bundle = sbs.createBundle("chrome://mozapps/locale/update/update.properties");
- var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
- .getService(Components.interfaces.nsIPromptService);
- ps.alert(aParentWindow,
- bundle.GetStringFromName("updatesdisabledtitle"),
- bundle.GetStringFromName("updatesdisabledmessage"));
- return;
- }
-
- switch (aSourceEvent) {
- case nsIUpdateService.SOURCE_EVENT_MISMATCH:
- case nsIUpdateService.SOURCE_EVENT_USER:
- if (aSourceEvent == nsIUpdateService.SOURCE_EVENT_USER &&
- gPref.getBoolPref(PREF_UPDATE_APP_PERFORMED)) {
- var sbs = Components.classes["@mozilla.org/intl/stringbundle;1"]
- .getService(Components.interfaces.nsIStringBundleService);
- var bundle = sbs.createBundle("chrome://mozapps/locale/update/update.properties");
- var brandBundle = sbs.createBundle("chrome://global/locale/brand.properties");
- var brandShortName = brandBundle.GetStringFromName("brandShortName");
- var message = bundle.formatStringFromName("appupdateperformedmessage",
- [brandShortName, brandShortName], 2);
- var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
- .getService(Components.interfaces.nsIPromptService);
- ps.alert(aParentWindow,
- bundle.GetStringFromName("appupdateperformedtitle"),
- message);
- return;
- }
-
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
- var wizard = wm.getMostRecentWindow("Update:Wizard");
- if (wizard)
- wizard.focus();
- else {
- 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);
- var updateTypes = Components.classes["@mozilla.org/supports-PRUint8;1"]
- .createInstance(Components.interfaces.nsISupportsPRUint8);
- updateTypes.data = types;
- ary.AppendElement(updateTypes);
- var sourceEvent = Components.classes["@mozilla.org/supports-PRUint8;1"]
- .createInstance(Components.interfaces.nsISupportsPRUint8);
- sourceEvent.data = aSourceEvent;
- ary.AppendElement(sourceEvent);
- for (var i = 0; i < aItems.length; ++i)
- ary.AppendElement(aItems[i]);
-
- var features = "chrome,centerscreen";
- if (aSourceEvent == nsIUpdateService.SOURCE_EVENT_MISMATCH) {
- features += ",modal"; // Must block in mismatch mode since there's
- // no main evt loop yet.
- }
-
- // This *must* be modal so as not to break startup! This code is invoked before
- // the main event loop is initiated (via checkForMismatches).
- ww.openWindow(aParentWindow, "chrome://mozapps/content/update/update.xul","", features, ary);
- }
- break;
- case nsIUpdateService.SOURCE_EVENT_BACKGROUND:
- // Rather than show a UI, call the checkForUpdates function directly here.
- // The Browser's inline front end update notification system listens for the
- // updates that this function broadcasts.
- this.checkForUpdatesInternal([], 0, types, aSourceEvent);
-
- break;
- }
- },
-
- _canUpdate: function (aPreference, aSourceEvent, aUpdateTypes)
- {
- // Always can update if the autoupdate preference is set, otherwise,
- // allow updates only when not in backround update mode, i.e. when the user
- // explicitly asked.
- return aPreference ? true
- : aSourceEvent != nsIUpdateService.SOURCE_EVENT_BACKGROUND;
- },
-
- checkForUpdatesInternal: function nsUpdateService_checkForUpdatesInternal (aItems, aItemCount, aUpdateTypes, aSourceEvent)
- {
- var types = this._getAllowedTypes(aUpdateTypes);
-
- // Listen for notifications sent out by the app updater (implemented here) and the
- // extension updater (implemented in nsExtensionItemUpdater)
- var canUpdate;
- this._updateObserver = new nsUpdateObserver(types, aSourceEvent, this);
- var os = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- if (types & nsIUpdateItem.TYPE_APP) {
- if (this._canUpdate(this._appAutoUpdateEnabled, aSourceEvent, types)) {
- gOS.addObserver(this._updateObserver, "Update:App:Ended", false);
-
- this._currentVersion = new nsAppUpdateInfo();
- this._newestVersion = new nsAppUpdateInfo();
-
- if (!this._updateObserver.appUpdater) {
- this._updateObserver.appUpdater = new nsAppUpdater(this);
- this._updateObserver.appUpdater.checkForUpdates();
- }
- }
- }
-
- // JMC: Check for silent updates
- if (types & nsIUpdateItem.TYPE_SILENT) {
- if (this._canUpdate(this._silentAutoUpdateEnabled, aSourceEvent, types)) {
- gOS.addObserver(this._updateObserver, "Update:Silent:Ended", false);
-
- this._currentVersion = new nsSilentUpdateInfo();
- this._newestVersion = new nsSilentUpdateInfo();
-
- if (!this._updateObserver.silentUpdater) {
- this._updateObserver.silentUpdater = new nsSilentUpdater(this);
- this._updateObserver.silentUpdater.checkForUpdates();
- }
- }
- }
-
-
- if (types & nsIUpdateItem.TYPE_ADDON) { // TYPE_EXTENSION, TYPE_ANY, etc.
- if (this._canUpdate(this._extAutoUpdateEnabled, aSourceEvent, types)) {
- gOS.addObserver(this._updateObserver, "Update:Extension:Started", false);
- gOS.addObserver(this._updateObserver, "Update:Extension:Item-Ended", false);
- gOS.addObserver(this._updateObserver, "Update:Extension:Ended", false);
-
- var em = Components.classes["@mozilla.org/extensions/manager;1"]
- .getService(Components.interfaces.nsIExtensionManager);
- em.update(aItems, aItems.length, false);
- }
- }
-
- if (aSourceEvent == nsIUpdateService.SOURCE_EVENT_BACKGROUND &&
- (this._appAutoUpdateEnabled || this._extAutoUpdateEnabled)) {
- if (types & nsIUpdateItem.TYPE_ADDON)
- gPref.setIntPref(PREF_UPDATE_EXTENSIONS_LASTUPDATEDATE, this._nowInMilliseconds / 1000);
- if (types & nsIUpdateItem.TYPE_APP)
- gPref.setIntPref(PREF_UPDATE_APP_LASTUPDATEDATE, this._nowInMilliseconds / 1000);
- if (types & nsIUpdateItem.TYPE_SILENT)
- gPref.setIntPref(PREF_SILENT_UPDATE_LASTUPDATEDATE, this._nowInMilliseconds / 1000);
- }
- },
-
- get updateCount()
- {
- // The number of available updates is the number of extension/theme/other
- // updates + 1 for an application update, if one is available.
- var updateCount = this.extensionUpdatesAvailable;
- if (this.appUpdatesAvailable)
- ++updateCount;
- return updateCount;
- },
-
- get updateSeverity()
- {
- return gPref.getIntPref(PREF_UPDATE_SEVERITY);
- },
-
- _appUpdatesAvailable: undefined,
- get appUpdatesAvailable()
- {
- if (this._appUpdatesAvailable === undefined) {
- return (gPref.prefHasUserValue(PREF_UPDATE_APP_UPDATESAVAILABLE) &&
- gPref.getBoolPref(PREF_UPDATE_APP_UPDATESAVAILABLE));
- }
- return this._appUpdatesAvailable;
- },
- set appUpdatesAvailable(aValue)
- {
- this._appUpdatesAvailable = aValue;
- return aValue;
- },
-
- _extensionUpdatesAvailable: undefined,
- get extensionUpdatesAvailable()
- {
- if (this._extensionUpdatesAvailable === undefined)
- return gPref.getIntPref(PREF_UPDATE_EXTENSIONS_COUNT);
- return this._extensionUpdatesAvailable;
- },
- set extensionUpdatesAvailable(aValue)
- {
- this._extensionUpdatesAvailable = aValue;
- return aValue;
- },
-
- _newestVersion: null,
- get newestVersion()
- {
- return this._newestVersion;
- },
- _currentVersion: null,
- get currentVersion()
- {
- return this._currentVersion;
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsITimerCallback
- _shouldUpdate: function nsUpdateService__shouldUpdate (aIntervalPref, aLastCheckPref)
- {
- var interval = gPref.getIntPref(aIntervalPref);
- var lastUpdateTime = gPref.getIntPref(aLastCheckPref);
- return ((Math.round(this._nowInMilliseconds/1000) - lastUpdateTime) > Math.round(interval/1000));
- },
-
- notify: function nsUpdateService_notify (aTimer)
- {
- //dump("******* Update service - might be time to update check... \n Timer is " + aTimer.delay);
- //dump("Ought to let your friends know when you're going to party");
- var types = 0;
- if (this._shouldUpdate(PREF_UPDATE_EXTENSIONS_INTERVAL,
- PREF_UPDATE_EXTENSIONS_LASTUPDATEDATE)) {
- types |= nsIUpdateItem.TYPE_ADDON;
- }
- if (this._shouldUpdate(PREF_UPDATE_APP_INTERVAL,
- PREF_UPDATE_APP_LASTUPDATEDATE)) {
- types |= nsIUpdateItem.TYPE_APP;
- }
- if (this._shouldUpdate(PREF_SILENT_UPDATE_INTERVAL,
- PREF_SILENT_UPDATE_LASTUPDATEDATE)) {
- types |= nsIUpdateItem.TYPE_SILENT;
- }
- if (types)
- this.checkForUpdatesInternal([], 0, types,
- nsIUpdateService.SOURCE_EVENT_BACKGROUND);
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsIObserver
- observe: function nsUpdateService_observe (aSubject, aTopic, aData)
- {
- switch (aTopic)
- {
- case "nsPref:changed":
- var needsNotification = false;
- switch (aData)
- {
- // MERC BILL, UPDATE AUTOINSTALL STATUS
- case PREF_UPDATE_APP_AUTOINSTALL:
- case PREF_UPDATE_EXTENSIONS_AUTOINSTALL:
- //this._appAutoInstallEnabled = gPref.getBoolPref(PREF_UPDATE_APP_AUTOINSTALL);
- //this._extensionsAutoInstallEnabled = gPref.getBoolPref(PREF_UPDATE_EXTENSIONS_AUTOINSTALL);
-
- case PREF_UPDATE_APP_AUTOUPDATEENABLED:
- case PREF_UPDATE_APP_ENABLED:
- this._appAutoUpdateEnabled = gPref.getBoolPref(PREF_UPDATE_APP_AUTOUPDATEENABLED);
- if (!this._appAutoUpdateEnabled)
- {
- this._clearAppUpdatePrefs();
- needsNotification = true;
- }
- else
- {
- // Do an initial check NOW to update any FE components and kick off the timer.
- this.checkForUpdatesInternal([], 0, nsIUpdateItem.TYPE_APP,
- nsIUpdateService.SOURCE_EVENT_BACKGROUND);
- }
- break;
- case PREF_UPDATE_EXTENSIONS_AUTOUPDATEENABLED:
- case PREF_UPDATE_EXTENSIONS_ENABLED:
- this._extAutoUpdateEnabled = gPref.getBoolPref(PREF_UPDATE_EXTENSIONS_AUTOUPDATEENABLED);
- if (!this._extAutoUpdateEnabled) {
- // Unset prefs used by the update service to signify extension updates
- if (gPref.prefHasUserValue(PREF_UPDATE_EXTENSIONS_COUNT))
- gPref.clearUserPref(PREF_UPDATE_EXTENSIONS_COUNT);
- needsNotification = true;
- }
- else {
- // Do an initial check NOW to update any FE components and kick off the
- // timer.
- this.checkForUpdatesInternal([], 0, nsIUpdateItem.TYPE_ADDON,
- nsIUpdateService.SOURCE_EVENT_BACKGROUND);
- }
- break;
- case PREF_UPDATE_INTERVAL:
- case PREF_UPDATE_APP_INTERVAL:
- case PREF_UPDATE_EXTENSIONS_INTERVAL:
- case PREF_SILENT_UPDATE_INTERVAL:
- this._makeTimer(gPref.getIntPref(PREF_UPDATE_INTERVAL));
- break;
- }
-
- if (needsNotification) {
- var os = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- var backgroundEvt = Components.interfaces.nsIUpdateService.SOURCE_EVENT_BACKGROUND;
- gOS.notifyObservers(null, "Update:Ended", backgroundEvt.toString());
- }
- break;
- case "xpcom-shutdown":
- gOS.removeObserver(this, "xpcom-shutdown");
-
- // Clean up held observers etc to avoid leaks.
- var pbi = gPref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
- pbi.removeObserver(PREF_UPDATE_APP_AUTOUPDATEENABLED, this);
- pbi.removeObserver(PREF_UPDATE_APP_ENABLED, this);
- pbi.removeObserver(PREF_UPDATE_EXTENSIONS_AUTOUPDATEENABLED, this);
- pbi.removeObserver(PREF_UPDATE_EXTENSIONS_ENABLED, this);
- pbi.removeObserver(PREF_UPDATE_INTERVAL, this);
- pbi.removeObserver(PREF_UPDATE_EXTENSIONS_INTERVAL, this);
-
- // MERC BILL
- pbi.removeObserver(PREF_UPDATE_APP_AUTOINSTALL, this);
- pbi.removeObserver(PREF_UPDATE_EXTENSIONS_AUTOINSTALL, this);
-
- // Release strongly held services.
- gPref = null;
- gRDF = null;
- gOS = null;
- if (this._timer) {
- this._timer.cancel();
- this._timer = null;
- }
- break;
- }
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsUpdateService
- _timer: null,
- _makeTimer: function nsUpdateService__makeTimer (aDelay)
- {
- if (!this._timer)
- this._timer = Components.classes["@mozilla.org/timer;1"]
- .createInstance(Components.interfaces.nsITimer);
- this._timer.cancel();
- this._timer.initWithCallback(this, aDelay,
- Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
- },
-
- get _nowInMilliseconds ()
- {
- var d = new Date();
- return Date.UTC(d.getUTCFullYear(),
- d.getUTCMonth(),
- d.getUTCDay(),
- d.getUTCHours(),
- d.getUTCMinutes(),
- d.getUTCSeconds(),
- d.getUTCMilliseconds());
- },
-
- _clearAppUpdatePrefs: function nsUpdateService__clearAppUpdatePrefs ()
- {
- // Unset prefs used by the update service to signify application updates
- if (gPref.prefHasUserValue(PREF_UPDATE_APP_UPDATESAVAILABLE))
- gPref.clearUserPref(PREF_UPDATE_APP_UPDATESAVAILABLE);
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsISupports
- QueryInterface: function nsUpdateService_QueryInterface (aIID)
- {
- if (!aIID.equals(Components.interfaces.nsIUpdateService) &&
- !aIID.equals(Components.interfaces.nsIObserver) &&
- !aIID.equals(Components.interfaces.nsISupports))
- throw Components.results.NS_ERROR_NO_INTERFACE;
- return this;
- }
- };
-
- function nsUpdateObserver(aUpdateTypes, aSourceEvent, aService)
- {
- this._updateTypes = aUpdateTypes;
- this._sourceEvent = aSourceEvent;
- this._service = aService;
- // MERC BILL PREF FOR AUTOINSTALL
- this._appAutoInstallEnabled = gPref.getBoolPref(PREF_UPDATE_APP_AUTOINSTALL);
- this._extensionsAutoInstallEnabled = gPref.getBoolPref(PREF_UPDATE_EXTENSIONS_AUTOINSTALL);
- /*
- if (this._appAutoInstallEnabled)
- //dump("\n\n**** AUTOINSTALL APP UPDATES...\n\n");
- if (this._extensionsAutoInstallEnabled)
- //dump("\n\n**** AUTOINSTALL EXTENSION UPDATES...\n\n");
- */
-
- }
-
- nsUpdateObserver.prototype = {
- _updateTypes: 0,
- _sourceEvent: 0,
- _updateState: 0,
- _endedTimer : null,
- _appAutoInstallEnabled : false,
- _extensionsAutoInstallEnabled : false,
- appUpdater: null,
- silentUpdater: null,
- items : null,
- itemCount : 0,
-
- get _doneUpdating()
- {
- var notBackground = this._sourceEvent != nsIUpdateService.SOURCE_EVENT_BACKGROUND;
- var canUpdateApp = this._service._appAutoUpdateEnabled ||
- (notBackground ? gPref.getBoolPref(PREF_UPDATE_APP_ENABLED)
- : false);
- var canUpdateExt = this._service._extAutoUpdateEnabled ||
- (notBackground ? gPref.getBoolPref(PREF_UPDATE_EXTENSIONS_ENABLED)
- : false);
-
- var test = 0;
- var updatingApp = (this._updateTypes & nsIUpdateItem.TYPE_APP) &&
- canUpdateApp;
- var updatingExt = (this._updateTypes & nsIUpdateItem.TYPE_ADDON) &&
- canUpdateExt;
- var updatingSilent = (this._updateTypes & nsIUpdateItem.TYPE_SILENT);
-
- if (updatingApp)
- test |= UPDATED_APP;
- if (updatingExt)
- test |= UPDATED_EXTENSIONS;
- if (updatingSilent)
- test |= UPDATED_SILENT;
-
- return (this._updateState & test) == test;
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsIObserver
- observe: function nsUpdateObserver_observe (aSubject, aTopic, aData)
- {
- switch (aTopic) {
- case "Update:Extension:Started":
- // Reset the count
- gPref.setIntPref(PREF_UPDATE_EXTENSIONS_COUNT, 0);
- break;
- case "Update:Extension:Item-Ended":
- var newCount = gPref.getIntPref(PREF_UPDATE_EXTENSIONS_COUNT) + 1;
- gPref.setIntPref(PREF_UPDATE_EXTENSIONS_COUNT, newCount);
- var threshold = gPref.getIntPref(PREF_UPDATE_EXTENSIONS_SEVERITY_THRESHOLD);
- if (this._service.updateSeverity < nsIUpdateService.SEVERITY_HIGH) {
- if (newCount > threshold)
- gPref.setIntPref(PREF_UPDATE_SEVERITY, nsIUpdateService.SEVERITY_MEDIUM);
- else
- gPref.setIntPref(PREF_UPDATE_SEVERITY, nsIUpdateService.SEVERITY_LOW);
- }
- break;
- case "Update:Extension:Ended":
- this._updateState |= UPDATED_EXTENSIONS;
- break;
- case "Update:App:Ended":
- this._updateState |= UPDATED_APP;
- this.appUpdater.destroy();
- this.appUpdater = null;
- break;
- case "Update:Silent:Ended":
- this._updateState |= UPDATED_SILENT;
- if (this.silentUpdater)
- {
- this.silentUpdater.destroy();
- this.silentUpdater = null;
- }
- break;
- }
-
- if (this._doneUpdating) {
- // Do the finalize stuff on a timer to let other observers have a chance to
- // handle
- if (this._endedTimer)
- this._endedTimer.cancel();
- this._endedTimer = Components.classes["@mozilla.org/timer;1"]
- .createInstance(Components.interfaces.nsITimer);
- this._endedTimer.initWithCallback(this, 0,
- Components.interfaces.nsITimer.TYPE_ONE_SHOT);
- }
- },
-
- notify: function nsUpdateObserver_notify (aTimer)
- {
-
-
- // //dump("UpdateObserver_notify: Ought to let your friends know when you're going to party");
- // The Inline Browser Update UI uses this notification to refresh its update
- // UI if necessary.
- gOS.notifyObservers(null, "Update:Ended", this._sourceEvent.toString());
-
- // Show update notification UI if:
- // We were updating any types and any item was found
- // We were updating extensions and an extension update was found.
- // We were updating app and an app update was found.
- var updatesAvailable = (((this._updateTypes & nsIUpdateItem.TYPE_EXTENSION) ||
- (this._updateTypes & nsIUpdateItem.TYPE_ANY)) &&
- gPref.getIntPref(PREF_UPDATE_EXTENSIONS_COUNT) != 0);
-
- if (!updatesAvailable)
- {
- updatesAvailable = ((this._updateTypes & nsIUpdateItem.TYPE_APP) ||
- (this._updateTypes & nsIUpdateItem.TYPE_ANY)) &&
- gPref.getBoolPref(PREF_UPDATE_APP_UPDATESAVAILABLE);
- }
-
- var showNotification = gPref.getBoolPref(PREF_UPDATE_SHOW_SLIDING_NOTIFICATION);
- if (showNotification && updatesAvailable &&
- this._sourceEvent == nsIUpdateService.SOURCE_EVENT_BACKGROUND) {
- var sbs = Components.classes["@mozilla.org/intl/stringbundle;1"]
- .getService(Components.interfaces.nsIStringBundleService);
- var bundle = sbs.createBundle("chrome://mozapps/locale/update/update.properties");
-
- var alertTitle = bundle.GetStringFromName("updatesAvailableTitle");
- var alertText = bundle.GetStringFromName("updatesAvailableText");
-
- var alerts = Components.classes["@mozilla.org/alerts-service;1"]
- .getService(Components.interfaces.nsIAlertsService);
-
- // MERC BILL SUPPORT AUTOINSTALL
- if (this._appAutoInstallEnabled)
- {
-
- this.autoUpdateInstall();
- }
- else
- {
- alerts.showAlertNotification("chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png",
- alertTitle, alertText, true, "", this);
- }
-
- }
-
- this.destroy();
- },
-
- autoUpdateInstall : function nsUpdateObserver_autoUpdateInstall ()
- {
- // Don't show the app update option or critical updates if the user has
- // already installed an app update but has not yet restarted.
-
- var updatePerformed = gPref.getBoolPref(PREF_UPDATE_APP_PERFORMED);
- if (!updatePerformed && this._updateTypes & nsIUpdateItem.TYPE_APP) {
- var updatesvc = Components.classes["@mozilla.org/updates/update-service;1"]
- .getService(Components.interfaces.nsIUpdateService);
- /* JMC: Why do we care about the currentVersion?
- var currentInfo = updatesvc.currentVersion;
- if (currentInfo) {
- var patches = currentInfo.getCollection("patches", { });
- var languages = this._currentInfo.getCollection("languages", { });
- }
- */
-
- var newestInfo = updatesvc.newestVersion;
- if (newestInfo) {
- var languages = newestInfo.getCollection("languages", { });
- var cr = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
- .getService(Components.interfaces.nsIXULChromeRegistry);
- var selectedLocale = cr.getSelectedLocale("global");
- var haveLanguage = false;
- for (var i = 0; i < languages.length; ++i) {
- if (languages[i].internalName == selectedLocale)
- haveLanguage = true;
- }
-
- var files = newestInfo.getCollection("files", { });
-
- // When the user upgrades the application, any optional components that
- // they have installed are automatically installed. If there are remaining
- // optional components that are not currently installed, then these
- // are offered as an option.
- /* JMC: Fixme, add optional components later
- var components = newestInfo.getCollection("optional", { });
- for (var i = 0; i < components.length; ++i) {
- if (InstallTrigger.getVersion(components[i].internalName))
- this.items.push(components[i].URL);
- }
- */
- this.items = [];
-
- var selectedLocaleAvailable = false;
- var languages = newestInfo.getCollection("languages", { });
- for (i = 0; i < languages.length; ++i) {
- if (languages[i].internalName == selectedLocale) {
- selectedLocaleAvailable = true;
- this.items.push(languages[i].URL);
- }
- }
-
- for (i = 0; i < files.length; ++i) {
- this.items.push(files[i].URL);
- }
-
- var xpimgr = Components.classes["@mozilla.org/xpinstall/install-manager;1"]
- .createInstance(Components.interfaces.nsIXPInstallManager);
-
- xpimgr.initManagerFromChrome(this.items, this.items.length, this);
- this.itemCount = this.items.length - 1;
- gPref.setBoolPref(PREF_UPDATE_APP_PERFORMED, true);
- }
- }
- },
-
- onStateChange: function (aIndex, aState, aValue)
- {
- // var strings = document.getElementById("updateStrings");
-
- var alerts = Components.classes["@mozilla.org/alerts-service;1"]
- .getService(Components.interfaces.nsIAlertsService);
-
- const nsIXPIProgressDialog = Components.interfaces.nsIXPIProgressDialog;
- switch (aState) {
- case nsIXPIProgressDialog.DOWNLOAD_START:
- break;
- case nsIXPIProgressDialog.DOWNLOAD_DONE:
- case nsIXPIProgressDialog.INSTALL_START:
- break;
- case nsIXPIProgressDialog.INSTALL_DONE:
- /*
- switch (aValue) {
- case 999:
- this._restartRequired = true;
- alerts.showAlertNotification("chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png",
- "Smart Update Notification", "Installation of patches is complete. Reboot is required.", false, "", null);
-
- break;
- case 0:
- alerts.showAlertNotification("chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png",
- "Smart Update Notification", "Installation of patches is complete.", false, "", null);
- break;
- default:
- // XXXben ignore chrome registration errors hack!
- if (!(aValue == -239 && gUpdateWizard.updatingApp)) {
- this._objs[aIndex].error = aValue;
- this._errors = true;
- }
- break;
- }
- */
- this.itemCount--;
- if (this.itemCount == 0) {
- alerts.showAlertNotification("chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png",
- "Smart Update Notification", "Installation of patches is complete.", false, "", null);
- }
- break;
- case nsIXPIProgressDialog.DIALOG_CLOSE:
- break;
- }
- },
-
- _objs: [],
- _errors: false,
-
- onProgress: function (aIndex, aValue, aMaxValue)
- {
- // var downloadProgress = document.getElementById("downloadProgress");
- // downloadProgress.value = Math.ceil((aValue/aMaxValue) * 100);
- },
-
-
- destroy: function nsUpdateObserver_destroy ()
- {
- try { gOS.removeObserver(this, "Update:Extension:Started"); } catch (e) { }
- try { gOS.removeObserver(this, "Update:Extension:Item-Ended"); } catch (e) { }
- try { gOS.removeObserver(this, "Update:Extension:Ended"); } catch (e) { }
- try { gOS.removeObserver(this, "Update:App:Ended"); } catch (e) { }
- try { gOS.removeObserver(this, "Update:Silent:Ended"); } catch (e) { }
-
- if (this._endedTimer) {
- this._endedTimer.cancel();
- this._endedTimer = null;
- }
- },
-
- ////////////////////////////////////////////////////////////////////////////
- // nsIAlertListener
- onAlertFinished: function nsUpdateObserver_onAlertFinished ()
- {
- },
-
- onAlertClickCallback: function nsUpdateObserver_onAlertClickCallback (aCookie)
- {
- var updates = Components.classes["@mozilla.org/updates/update-service;1"]
- .getService(Components.interfaces.nsIUpdateService);
- updates.checkForUpdates([], 0, Components.interfaces.nsIUpdateItem.TYPE_ANY,
- Components.interfaces.nsIUpdateService.SOURCE_EVENT_USER,
- null);
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsISupports
- QueryInterface: function nsUpdateObserver_QueryInterface (aIID)
- {
- if (!aIID.equals(Components.interfaces.nsIObserver) &&
- !aIID.equals(Components.interfaces.nsIAlertListener) &&
- !aIID.equals(Components.interfaces.nsISupports))
- throw Components.results.NS_ERROR_NO_INTERFACE;
- return this;
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////////
- // App Updater
- function nsAppUpdater(aUpdateService)
- {
- this._service = aUpdateService;
- }
-
- nsAppUpdater.prototype = {
- _service : null,
-
- checkForUpdates: function ()
- {
- // TEMP TEST
- //dump("start update CHECK!\n");
-
- var dsURI = gPref.getComplexValue(PREF_UPDATE_APP_URI,
- Components.interfaces.nsIPrefLocalizedString).data;
- dsURI += "?" + Math.round(Math.random() * 1000);
- this._ds = gRDF.GetDataSource(dsURI);
- var rds = this._ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource)
- if (rds.loaded)
- this.onDatasourceLoaded(this._ds);
- else {
- var sink = this._ds.QueryInterface(Components.interfaces.nsIRDFXMLSink);
-
- // Creates a strong ref that holds this object past when it falls out of
- // scope in the calling function
- sink.addXMLSinkObserver(this);
- }
- },
-
- destroy: function ()
- {
- var sink = this._ds.QueryInterface(Components.interfaces.nsIRDFXMLSink);
- sink.removeXMLSinkObserver(this);
- this._service = null;
- },
-
- /////////////////////////////////////////////////////////////////////////////
- //
- _ncR: function nsUpdateService__ncR (aProperty)
- {
- return gRDF.GetResource("http://home.netscape.com/NC-rdf#" + aProperty);
- },
-
- _getPropertyFromResource: function nsAppUpdater__getPropertyFromResource (aDataSource,
- aSourceResource,
- aProperty)
- {
- var rv;
- try {
- var property = gRDF.GetResource(APP_NS(aProperty));
- rv = this._stringData(aDataSource.GetTarget(aSourceResource, property, true));
- if (rv == "--")
- throw Components.results.NS_ERROR_FAILURE;
- }
- catch (e) {
- return null;
- }
- return rv;
- },
-
- _stringData: function nsAppUpdater__stringData (aLiteralOrResource)
- {
- try {
- var obj = aLiteralOrResource.QueryInterface(Components.interfaces.nsIRDFLiteral);
- return obj.Value;
- }
- catch (e) {
- try {
- obj = aLiteralOrResource.QueryInterface(Components.interfaces.nsIRDFResource);
- return obj.Value;
- }
- catch (e) {}
- }
- return "--";
- },
-
- /////////////////////////////////////////////////////////////////////////////
- //
- onDatasourceLoaded: function nsAppUpdater_onDatasourceLoaded (aDataSource)
- {
- //dump("get ID\n");
- var appID = gPref.getCharPref(PREF_APP_ID);
- //dump("get app version\n");
- var appVersion = gPref.getCharPref(PREF_APP_VERSION);
- //dump("after getting both\n");
-
- var appResource = gRDF.GetResource("urn:mozilla:app:" + appID);
- var updatesArc = gRDF.GetResource(APP_NS("updates"));
- var updatesResource = aDataSource.GetTarget(appResource, updatesArc, true);
-
- try {
- updatesResource = updatesResource.QueryInterface(Components.interfaces.nsIRDFResource);
- }
- catch (e) {
- //dump("++++ ACK! Bailed out from updatesResource QueryInterface call.\n\n");
- gOS.notifyObservers(null, "Update:App:Error", "");
- gOS.notifyObservers(null, "Update:App:Ended", "");
- return;
- }
-
- var cu = Components.classes["@mozilla.org/rdf/container-utils;1"]
- .getService(Components.interfaces.nsIRDFContainerUtils);
- if (cu.IsContainer(aDataSource, updatesResource)) {
- var c = Components.classes["@mozilla.org/rdf/container;1"]
- .getService(Components.interfaces.nsIRDFContainer);
- c.Init(aDataSource, updatesResource);
-
- var versionChecker = Components.classes["@mozilla.org/updates/version-checker;1"]
- .getService(Components.interfaces.nsIVersionChecker);
-
- var newestVersionObj = { version: appVersion, resource: null };
- var updates = c.GetElements();
- while (updates.hasMoreElements()) {
- var update = updates.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
- var version = this._getPropertyFromResource(aDataSource, update, "version");
- if (!version)
- continue;
- if (versionChecker.compare(appVersion, version) == 0)
- this._parseVersionData(aDataSource, update, this._service._currentVersion);
- else if (versionChecker.compare(newestVersionObj.version, version) < 0) {
- newestVersionObj.version = version;
- newestVersionObj.resource = update;
- }
- }
- if (newestVersionObj.resource) {
- //dump("\n\n+++++ We think we've got a new version available... \n\n");
- this._parseVersionData(aDataSource, newestVersionObj.resource, this._service._newestVersion);
- }
- // There is a newer version of the app available or there are any critical
- // patches available update the severity and available updates preferences.
- // XXXben also note if there are langpacks available that match the user's
- // preference if they previously installed an app update when a
- // langpack for their language was not available and they used another
- // in the meantime.
- var haveLanguage = false;
- var patches = this._service._currentVersion.patches;
- var languages = this._service._newestVersion.languages;
- if (languages) {
- var cr = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
- .getService(Components.interfaces.nsIXULChromeRegistry);
- var selectedLocale = cr.getSelectedLocale("global");
- for (var i = 0; i < languages.length; ++i) {
- if (languages[i].internalName == selectedLocale)
- haveLanguage = true;
- }
- }
-
- if ((haveLanguage && (newestVersionObj.version != appVersion)) ||
- (patches && patches.length > 0)) {
- gPref.setIntPref(PREF_UPDATE_SEVERITY, 2);
- gPref.setBoolPref(PREF_UPDATE_APP_UPDATESAVAILABLE, true);
- }
- else
- gPref.setBoolPref(PREF_UPDATE_APP_UPDATESAVAILABLE, false);
-
- if (!gPref.getBoolPref(PREF_UPDATE_APP_UPDATESAVAILABLE)) {
- this._service._clearAppUpdatePrefs();
-
- // Lower the severity to reflect the fact that there are now only Extension/
- // Theme updates available
- var newCount = gPref.getIntPref(PREF_UPDATE_EXTENSIONS_COUNT);
- var threshold = gPref.getIntPref(PREF_UPDATE_EXTENSIONS_SEVERITY_THRESHOLD);
- if (newCount >= threshold)
- gPref.setIntPref(PREF_UPDATE_SEVERITY, nsIUpdateService.SEVERITY_MEDIUM);
- else
- gPref.setIntPref(PREF_UPDATE_SEVERITY, nsIUpdateService.SEVERITY_LOW);
- }
- }
-
- // The Update Wizard uses this notification to determine that the application
- // update process is now complete.
- gOS.notifyObservers(null, "Update:App:Ended", "");
- },
-
- _parseVersionData: function nsAppUpdater__parseVersionData (aDataSource,
- aUpdateResource,
- aTargetObj)
- {
- aTargetObj.updateVersion = this._getPropertyFromResource(aDataSource, aUpdateResource, "version");
- aTargetObj.updateDisplayVersion = this._getPropertyFromResource(aDataSource, aUpdateResource, "displayVersion");
- if (!aTargetObj.updateDisplayVersion)
- aTargetObj.updateDisplayVersion = this._getPropertyFromResource(aDataSource, aUpdateResource, "version");
- aTargetObj.updateInfoURL = this._getPropertyFromResource(aDataSource, aUpdateResource, "infoURL");
-
- aTargetObj.features = this._parseUpdateCollection(aDataSource, aUpdateResource, "features");
- aTargetObj.files = this._parseUpdateCollection(aDataSource, aUpdateResource, "files");
- aTargetObj.optional = this._parseUpdateCollection(aDataSource, aUpdateResource, "optional");
- aTargetObj.languages = this._parseUpdateCollection(aDataSource, aUpdateResource, "languages");
- aTargetObj.patches = this._parseUpdateCollection(aDataSource, aUpdateResource, "patches");
- // this._dumpProps(aTargetObj);
- },
-
-
- _parseUpdateCollection: function nsAppUpdater__parseUpdateCollection (aDataSource,
- aUpdateResource,
- aCollectionName)
- {
- if (!aUpdateResource)
- return null;
-
- var result = [];
-
- var collectionArc = gRDF.GetResource(APP_NS(aCollectionName));
- var collectionResource = aDataSource.GetTarget(aUpdateResource, collectionArc, true);
-
- try {
- collectionResource = collectionResource.QueryInterface(Components.interfaces.nsIRDFResource);
- }
- catch (e) { return null; }
-
- var cu = Components.classes["@mozilla.org/rdf/container-utils;1"]
- .getService(Components.interfaces.nsIRDFContainerUtils);
- if (cu.IsContainer(aDataSource, collectionResource)) {
- var c = Components.classes["@mozilla.org/rdf/container;1"]
- .getService(Components.interfaces.nsIRDFContainer);
- c.Init(aDataSource, collectionResource);
-
- var elements = c.GetElements();
- var fileArc = gRDF.GetResource(APP_NS("file"));
- var platform = getOSKey();
- while (elements.hasMoreElements()) {
- var element = elements.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
- var info = new nsAppUpdateInfoItem();
- info.name = this._getPropertyFromResource(aDataSource, element, "name");
- info.internalName = this._getPropertyFromResource(aDataSource, element, "internalName");
-
- // Each Component has a set of app:file arcs out, which reference resources with two
- // properties: app:platform and app:URL. If we find a resource whose app:platform value
- // matches the platform we're running on, we use the app:URL property on that resource
- // as the XPI URL, otherwise we use the default app:URL property on the Component
- // resource. (It must be a cross-platform piece, e.g. a language pack)
- // XXXben - what to do when platform not supported? We need some way to abort
- // and tell the app that this update is not available.
- var files = aDataSource.GetTargets(element, fileArc, true);
- while (files.hasMoreElements()) {
- var file = files.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
- if (platform == this._getPropertyFromResource(aDataSource, file, "platform")) {
- info.URL = this._getPropertyFromResource(aDataSource, file, "URL");
- break;
- }
- }
- if (!info.URL)
- info.URL = this._getPropertyFromResource(aDataSource, element, "URL");
- info.infoURL = this._getPropertyFromResource(aDataSource, element, "infoURL");
- info.description = this._getPropertyFromResource(aDataSource, element, "description");
- result.push(info);
- }
- }
-
- return result;
- },
-
- onDatasourceError: function (aStatus, aErrorMsg)
- {
- gOS.notifyObservers(null, "Update:App:Error", "");
- gOS.notifyObservers(null, "Update:App:Ended", "");
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsIRDFXMLSinkObserver
- onBeginLoad: function(aSink)
- {
- },
- onInterrupt: function(aSink)
- {
- },
- onResume: function(aSink)
- {
- },
-
- onEndLoad: function(aSink)
- {
- try {
- this._ds = aSink.QueryInterface(Components.interfaces.nsIRDFDataSource);
- this.onDatasourceLoaded(this._ds);
- }
- catch (e) { }
- },
-
- onError: function(aSink, aStatus, aErrorMsg)
- {
- try {
- this._ds = aSink.QueryInterface(Components.interfaces.nsIRDFDataSource);
- this.onDatasourceError(aStatus, aErrorMsg);
- }
- catch (e) { }
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsISupports
- QueryInterface: function nsAppUpdater_QueryInterface (aIID)
- {
- if (!aIID.equals(Components.interfaces.nsIRDFXMLSinkObserver) &&
- !aIID.equals(Components.interfaces.nsISupports))
- throw Components.results.NS_ERROR_NO_INTERFACE;
- return this;
- }
- }
-
-
- // Silent Updater
-
-
- ///////////////////////////////////////////////////////////////////////////////
- function nsSilentUpdater(aUpdateService)
- {
- // dump("SILENT UPDATE: Constructing the Silent Updater\n");
- this._service = aUpdateService;
- }
-
- nsSilentUpdater.prototype = {
- _service : null,
-
- _dumpProps : function dumpProps(obj, parent) {
- //dump("Dumping props for aTargetObjs\n\n");
- // Go through all the properties of the passed-in object
- for (var i in obj) {
- // if a parent (2nd parameter) was passed in, then use that to
- // build the message. Message includes i (the object's property name)
- // then the object's property value on a new line
- if (parent) { var msg = parent + "." + i + "\n" + obj[i]; } else { var msg = i + "\n" + obj[i]; }
- // Display the message. If the user clicks "OK", then continue. If they
- // click "CANCEL" then quit this level of recursion
- dump("+++++ " + msg);
- // if (!confirm(msg)) { return; }
- // If this property (i) is an object, then recursively process the object
- if (typeof obj[i] == "object") {
- if (parent) { dumpProps(obj[i], parent + "." + i); } else { dumpProps(obj[i], i); }
- }
- }
- },
-
- checkForUpdates: function ()
- {
- var dsURI = gPref.getComplexValue(PREF_UPDATE_APP_URI,
- Components.interfaces.nsIPrefLocalizedString).data;
- dsURI += "?" + Math.round(Math.random() * 1000);
- this._ds = gRDF.GetDataSource(dsURI);
- var rds = this._ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource)
- if (rds.loaded)
- this.onDatasourceLoaded(this._ds);
- else {
- var sink = this._ds.QueryInterface(Components.interfaces.nsIRDFXMLSink);
-
- // Creates a strong ref that holds this object past when it falls out of
- // scope in the calling function
- sink.addXMLSinkObserver(this);
- }
- },
-
- destroy: function ()
- {
- // dump("SILENT UPDATE: destroy function\n");
- //stackTrace(this);
- /*
- var sink = this._ds.QueryInterface(Components.interfaces.nsIRDFXMLSink);
- sink.removeXMLSinkObserver(this);
- this._service = null;
- */
- },
-
- /////////////////////////////////////////////////////////////////////////////
- //
- _ncR: function nsUpdateService__ncR (aProperty)
- {
- return gRDF.GetResource("http://home.netscape.com/NC-rdf#" + aProperty);
- },
-
- _getPropertyFromResource: function nsSilentUpdater__getPropertyFromResource (aDataSource,
- aSourceResource,
- aProperty)
- {
- var rv;
- try {
- var property = gRDF.GetResource(SILENT_NS(aProperty));
- rv = this._stringData(aDataSource.GetTarget(aSourceResource, property, true));
- if (rv == "--")
- throw Components.results.NS_ERROR_FAILURE;
- }
- catch (e) {
- return null;
- }
- return rv;
- },
-
- _stringData: function nsSilentUpdater__stringData (aLiteralOrResource)
- {
- try {
- var obj = aLiteralOrResource.QueryInterface(Components.interfaces.nsIRDFLiteral);
- return obj.Value;
- }
- catch (e) {
- try {
- obj = aLiteralOrResource.QueryInterface(Components.interfaces.nsIRDFResource);
- return obj.Value;
- }
- catch (e) {}
- }
- return "--";
- },
-
- /////////////////////////////////////////////////////////////////////////////
- //
- onDatasourceLoaded: function nsSilentUpdater_onDatasourceLoaded (aDataSource)
- {
- // dump("SILENT UPDATE: Got the update.rdf, parsing...\n");
- var silentVersion = gPref.getCharPref(PREF_SAFETYNET_VERSION);
-
- var silentResource = gRDF.GetResource("urn:netscape:silent");
- var updatesArc = gRDF.GetResource(SILENT_NS("updates"));
- var updatesResource = aDataSource.GetTarget(silentResource, updatesArc, true);
-
- try {
- updatesResource = updatesResource.QueryInterface(Components.interfaces.nsIRDFResource);
- }
- catch (e) {
- //dump("++++ ACK! Bailed out from updatesResource QueryInterface call.\n\n");
- gOS.notifyObservers(null, "Update:Silent:Error", "");
- gOS.notifyObservers(null, "Update:Silent:Ended", "");
- return;
- }
-
- var cu = Components.classes["@mozilla.org/rdf/container-utils;1"]
- .getService(Components.interfaces.nsIRDFContainerUtils);
- if (cu.IsContainer(aDataSource, updatesResource)) {
- var c = Components.classes["@mozilla.org/rdf/container;1"]
- .getService(Components.interfaces.nsIRDFContainer);
- c.Init(aDataSource, updatesResource);
-
- var versionChecker = Components.classes["@mozilla.org/updates/version-checker;1"]
- .getService(Components.interfaces.nsIVersionChecker);
-
- var newestVersionObj = { version: silentVersion, resource: null };
- var biggestMinorObj = { version: silentVersion, resource: null };
- var updates = c.GetElements();
- while (updates.hasMoreElements()) {
- var update = updates.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
- var version = this._getPropertyFromResource(aDataSource, update, "version");
- if (!version)
- continue;
-
- if (versionChecker.compare(silentVersion, version) == 0)
- this._parseVersionData(aDataSource, update, this._service._currentVersion);
- else if (versionChecker.compare(newestVersionObj.version, version) < 0) {
- newestVersionObj.version = version;
- newestVersionObj.resource = update;
- }
- if (versionChecker.biggestMinor(silentVersion, version)) {
- biggestMinorObj.version = version;
- biggestMinorObj.resource = update;
- }
- }
- var files;
- if (biggestMinorObj.resource) {
- // dump("SILENT UPDATE: Got a patch, gonna install it...\n");
- this._parseVersionData(aDataSource, biggestMinorObj.resource, this._service._newestVersion);
- // files = this._service._newestVersion.patches;
- // Because we're only patching, we're not guaranteed to be the newest
- // So update again right away
- if (biggestMinorObj.version != newestVersionObj.version)
- {
- gPref.setIntPref(PREF_SILENT_UPDATE_LASTUPDATEDATE, 0); // JMC : doublecheck this?
- }
- files = this._service._newestVersion.getCollection("patches", { });
- if (files)
- {
- this.items = [];
- for (i = 0; i < files.length; ++i) {
- this.items.push(files[i].URL);
- // dump("SILENT UPDATE: Pushing " + files[i].URL + " into the URL list...\n");
- }
- }
- } else if (newestVersionObj.resource) {
- // dump("SILENT UPDATE: Got a new version, gonna install it...\n");
- this._parseVersionData(aDataSource, newestVersionObj.resource, this._service._newestVersion);
- // this._service._newestVersion.files;
- // dump("Dumping properties of _newestVersion\n");
- // this._dumpProps(this._service._newestVersion);
- files = this._service._newestVersion.getCollection("files", { });
-
- if (files)
- {
- this.items = [];
- for (i = 0; i < files.length; ++i) {
- this.items.push(files[i].URL);
- // dump("SILENT UPDATE: Pushing " + files[i].URL + " into the URL list...\n");
- }
- }
- }
-
- if (this.items)
- {
- var xpimgr = Components.classes["@mozilla.org/xpinstall/install-manager;1"]
- .createInstance(Components.interfaces.nsIXPInstallManager);
- xpimgr.initManagerFromChrome(this.items, this.items.length, this);
- }
- }
- // The Update Wizard uses this notification to determine that the application
- // update process is now complete.
- gOS.notifyObservers(null, "Update:Silent:Ended", "");
- },
-
- _parseVersionData: function nsSilentUpdater__parseVersionData (aDataSource,
- aUpdateResource,
- aTargetObj)
- {
- // dump ("SILENT UPDATE: in the parseVersionData function, with the " + aTargetObj + " target object\n");
- aTargetObj.updateVersion = this._getPropertyFromResource(aDataSource, aUpdateResource, "version");
- aTargetObj.files = this._parseUpdateCollection(aDataSource, aUpdateResource, "files");
- aTargetObj.patches = this._parseUpdateCollection(aDataSource, aUpdateResource, "patches");
- },
-
- _parseUpdateCollection: function nsSilentUpdater__parseUpdateCollection (aDataSource,
- aUpdateResource,
- aCollectionName)
- {
- // dump("SILENT UPDATE: in parseUpdateCollection with a resource of \n");
- if (!aUpdateResource)
- return null;
-
- var result = [];
-
- var collectionArc = gRDF.GetResource(SILENT_NS(aCollectionName));
- var collectionResource = aDataSource.GetTarget(aUpdateResource, collectionArc, true);
-
- try {
- collectionResource = collectionResource.QueryInterface(Components.interfaces.nsIRDFResource);
- }
- catch (e) { return null; }
-
- var cu = Components.classes["@mozilla.org/rdf/container-utils;1"]
- .getService(Components.interfaces.nsIRDFContainerUtils);
- if (cu.IsContainer(aDataSource, collectionResource)) {
- var c = Components.classes["@mozilla.org/rdf/container;1"]
- .getService(Components.interfaces.nsIRDFContainer);
- c.Init(aDataSource, collectionResource);
-
- var elements = c.GetElements();
- var fileArc = gRDF.GetResource(SILENT_NS("file"));
- var platform = getOSKey();
- while (elements.hasMoreElements()) {
- var element = elements.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
- var info = new nsSilentUpdateInfoItem();
- info.name = this._getPropertyFromResource(aDataSource, element, "name");
- info.internalName = this._getPropertyFromResource(aDataSource, element, "internalName");
-
- // Each Component has a set of app:file arcs out, which reference resources with two
- // properties: app:platform and app:URL. If we find a resource whose app:platform value
- // matches the platform we're running on, we use the app:URL property on that resource
- // as the XPI URL, otherwise we use the default app:URL property on the Component
- // resource. (It must be a cross-platform piece, e.g. a language pack)
- // XXXben - what to do when platform not supported? We need some way to abort
- // and tell the app that this update is not available.
- var files = aDataSource.GetTargets(element, fileArc, true);
- while (files.hasMoreElements()) {
- var file = files.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
- if (platform == this._getPropertyFromResource(aDataSource, file, "platform")) {
- info.URL = this._getPropertyFromResource(aDataSource, file, "URL");
- break;
- }
- }
- if (!info.URL)
- info.URL = this._getPropertyFromResource(aDataSource, element, "URL");
- info.infoURL = this._getPropertyFromResource(aDataSource, element, "infoURL");
- info.description = this._getPropertyFromResource(aDataSource, element, "description");
- result.push(info);
- }
- }
-
- return result;
- },
-
- onDatasourceError: function (aStatus, aErrorMsg)
- {
- gOS.notifyObservers(null, "Update:Silent:Error", "");
- gOS.notifyObservers(null, "Update:Silent:Ended", "");
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsIRDFXMLSinkObserver
- onBeginLoad: function(aSink) { },
- onInterrupt: function(aSink) { },
- onResume: function(aSink) { },
- onEndLoad: function(aSink)
- {
- try {
- this._ds = aSink.QueryInterface(Components.interfaces.nsIRDFDataSource);
- this.onDatasourceLoaded(this._ds);
- }
- catch (e) { }
- },
-
- onError: function(aSink, aStatus, aErrorMsg)
- {
- try {
- this._ds = aSink.QueryInterface(Components.interfaces.nsIRDFDataSource);
- this.onDatasourceError(aStatus, aErrorMsg);
- }
- catch (e) { }
- },
-
- onStateChange: function (aIndex, aState, aValue)
- {
- // dump("SILENT UPDATE: onStateChange observer of the XPInstall process\n");
- const nsIXPIProgressDialog = Components.interfaces.nsIXPIProgressDialog;
- switch (aState) {
- case nsIXPIProgressDialog.DOWNLOAD_START:
- break;
- case nsIXPIProgressDialog.DOWNLOAD_DONE:
- case nsIXPIProgressDialog.INSTALL_START:
- break;
- case nsIXPIProgressDialog.INSTALL_DONE:
- // Set pref to installed version number
- // dump("SILENT UPDATE: setting version pref to " + this._service._newestVersion.updateVersion + "\n");
- gPref.setCharPref(PREF_SAFETYNET_VERSION, this._service._newestVersion.updateVersion);
- gSiteControls.pollForNewTrustData();
- break;
- }
-
- },
-
- _objs: [],
- _errors: false,
-
- onProgress: function (aIndex, aValue, aMaxValue)
- {
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsISupports
- QueryInterface: function nsSilentUpdater_QueryInterface (aIID)
- {
- if (!aIID.equals(Components.interfaces.nsIObserver) &&
- !aIID.equals(Components.interfaces.nsIRDFXMLSinkObserver) &&
- !aIID.equals(Components.interfaces.nsISupports))
- throw Components.results.NS_ERROR_NO_INTERFACE;
- return this;
- }
- }
-
- // End Silent Updater
-
- function UpdateItem ()
- {
- }
-
- UpdateItem.prototype = {
- init: function UpdateItem_init (aID,
- aVersion,
- aMinAppVersion,
- aMaxAppVersion,
- aName,
- aRow,
- aXPIURL,
- aIconURL,
- aUpdateRDF,
- aType)
- {
- this._id = aID;
- this._version = aVersion;
- this._minAppVersion = aMinAppVersion;
- this._maxAppVersion = aMaxAppVersion;
- this._name = aName;
- this._row = aRow;
- this._xpiURL = aXPIURL;
- this._iconURL = aIconURL;
- this._updateRDF = aUpdateRDF;
- this._type = aType;
- },
-
- get id() { return this._id; },
- get version() { return this._version; },
- get minAppVersion() { return this._minAppVersion; },
- get maxAppVersion() { return this._maxAppVersion; },
- get name() { return this._name; },
- get row() { return this._row; },
- get xpiURL() { return this._xpiURL; },
- get iconURL() { return this._iconURL },
- get updateRDF() { return this._updateRDF; },
- get type() { return this._type; },
-
- get objectSource()
- {
- return { id : this._id,
- version : this._version,
- minAppVersion : this._minAppVersion,
- maxAppVersion : this._maxAppVersion,
- name : this._name,
- row : this._row,
- xpiURL : this._xpiURL,
- iconURL : this._iconURL,
- updateRDF : this._updateRDF,
- type : this._type
- }.toSource();
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsISupports
- QueryInterface: function UpdateItem_QueryInterface (aIID)
- {
- if (!aIID.equals(Components.interfaces.nsIUpdateItem) &&
- !aIID.equals(Components.interfaces.nsISupports))
- throw Components.results.NS_ERROR_NO_INTERFACE;
- return this;
- }
- };
-
- function nsAppUpdateInfoItem ()
- {
- }
- nsAppUpdateInfoItem.prototype = {
- internalName: "",
- name : "",
- URL : "",
- infoURL : "",
-
- /////////////////////////////////////////////////////////////////////////////
- // nsISupports
- QueryInterface: function nsAppUpdater_QueryInterface (aIID)
- {
- if (!aIID.equals(Components.interfaces.nsIAppUpdateInfo) &&
- !aIID.equals(Components.interfaces.nsISupports))
- throw Components.results.NS_ERROR_NO_INTERFACE;
- return this;
- }
- };
-
- function nsSilentUpdateInfoItem ()
- {
- }
- nsSilentUpdateInfoItem.prototype = {
- internalName: "",
- name : "",
- URL : "",
- infoURL : "",
-
- /////////////////////////////////////////////////////////////////////////////
- // nsISupports
- QueryInterface: function nsSilentUpdater_QueryInterface (aIID)
- {
- if (!aIID.equals(Components.interfaces.nsISilentUpdateInfo) &&
- !aIID.equals(Components.interfaces.nsISupports))
- throw Components.results.NS_ERROR_NO_INTERFACE;
- return this;
- }
- };
-
- function nsAppUpdateInfo ()
- {
- }
- nsAppUpdateInfo.prototype = {
- updateVersion : "",
- updateDisplayVersion: "",
- updateInfoURL : "",
-
- features : [],
- files : [],
- optional : [],
- languages : [],
- patches : [],
-
- getCollection: function (aCollectionName, aItemCount)
- {
- var collection = aCollectionName in this ? this[aCollectionName] : null;
- aItemCount.value = collection ? collection.length : 0;
- return collection;
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsISupports
- QueryInterface: function nsAppUpdater_QueryInterface (aIID)
- {
- if (!aIID.equals(Components.interfaces.nsIAppUpdateInfoCollection) &&
- !aIID.equals(Components.interfaces.nsISupports))
- throw Components.results.NS_ERROR_NO_INTERFACE;
- return this;
- }
- };
-
-
- function nsSilentUpdateInfo ()
- {
- }
- nsSilentUpdateInfo.prototype = {
- updateVersion : "",
- updateDisplayVersion: "",
- updateInfoURL : "",
-
- features : [],
- files : [],
- patches : [],
-
- getCollection: function (aCollectionName, aItemCount)
- {
- var collection = aCollectionName in this ? this[aCollectionName] : null;
- aItemCount.value = collection ? collection.length : 0;
- return collection;
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsISupports
- QueryInterface: function nsSilentUpdater_QueryInterface (aIID)
- {
- if (!aIID.equals(Components.interfaces.nsISilentUpdateInfoCollection) &&
- !aIID.equals(Components.interfaces.nsISupports))
- throw Components.results.NS_ERROR_NO_INTERFACE;
- return this;
- }
- };
-
- function Version(aMajor, aMinor, aRelease, aBuild, aPlus)
- {
- this.major = aMajor || 0;
- this.minor = aMinor || 0;
- this.release = aRelease || 0;
- this.build = aBuild || 0;
- this.plus = aPlus || 0;
- }
-
- Version.prototype = {
- toString: function Version_toString()
- {
- return this.major + "." + this.minor + "." + this.subminor + "." + this.release + (this.plus ? "+" : "");
- },
-
- compare: function (aVersion)
- {
- var fields = ["major", "minor", "release", "build", "plus"];
-
- for (var i = 0; i < fields.length; ++i) {
- var field = fields[i];
- if (aVersion[field] > this[field])
- return -1;
- else if (aVersion[field] < this[field])
- return 1;
- }
- return 0;
- }
- }
-
- function nsVersionChecker()
- {
- }
-
- nsVersionChecker.prototype = {
- /////////////////////////////////////////////////////////////////////////////
- // nsIVersionChecker
-
- // -ve if B is newer
- // equal if A == B
- // +ve if A is newer
- compare: function nsVersionChecker_compare (aVersionA, aVersionB)
- {
- var a = this._decomposeVersion(aVersionA);
- var b = this._decomposeVersion(aVersionB);
-
- return a.compare(b);
- },
-
- biggestMinor: function nsVersionChecker_biggestMinor (aVersionA, aVersionB)
- {
- // dump ("SILENT UPDATE, biggest minor check\n");
- var a = this._decomposeVersion(aVersionA);
- var b = this._decomposeVersion(aVersionB);
-
- if (a.major == b.major &&
- a.minor == b.minor)
- {
- if (a.build == 23) // last build of the day, look for tomorrow's latest
- {
- if (a.release == (b.release - 1))
- return true;
- } else {
- if ((a.release == b.release) &&
- (b.build == 23 ))
- {
- return true;
- }
- }
- }
- return false;
- },
-
- _decomposeVersion: function nsVersionChecker__decomposeVersion (aVersion)
- {
- var plus = 0;
- if (aVersion.charAt(aVersion.length-1) == "+") {
- aVersion = aVersion.substr(0, aVersion.length-1);
- plus = 1;
- }
-
- var parts = aVersion.split(".");
-
- return new Version(this._getValidInt(parts[0]),
- this._getValidInt(parts[1]),
- this._getValidInt(parts[2]),
- this._getValidInt(parts[3]),
- plus);
- },
-
- _getValidInt: function nsVersionChecker__getValidInt (aPartString)
- {
- var integer = parseInt(aPartString);
- if (isNaN(integer))
- return 0;
- return integer;
- },
-
- isValidVersion: function nsVersionChecker_isValidVersion (aVersion)
- {
- var parts = aVersion.split(".");
- if (parts.length == 0)
- return false;
- for (var i = 0; i < parts.length; ++i) {
- var part = parts[i];
- if (i == parts.length - 1) {
- if (part.lastIndexOf("+") != -1)
- parts[i] = part.substr(0, part.length - 1);
- }
- var integer = parseInt(part);
- if (isNaN(integer))
- return false;
- }
- return true;
- },
-
- /////////////////////////////////////////////////////////////////////////////
- // nsISupports
- QueryInterface: function nsVersionChecker_QueryInterface (aIID)
- {
- if (!aIID.equals(Components.interfaces.nsIVersionChecker) &&
- !aIID.equals(Components.interfaces.nsISupports))
- throw Components.results.NS_ERROR_NO_INTERFACE;
- return this;
- }
- };
-
- 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("{B3C290A6-3943-4B89-8BBE-C01EB7B3B311}"),
- contractID: "@mozilla.org/updates/update-service;1",
- className: "Update Service",
- factory: {
- createInstance: function (aOuter, aIID)
- {
- if (aOuter != null)
- throw Components.results.NS_ERROR_NO_AGGREGATION;
-
- return (new nsUpdateService()).QueryInterface(aIID);
- }
- }
- },
- version: { CID: Components.ID("{9408E0A5-509E-45E7-80C1-0F35B99FF7A9}"),
- contractID: "@mozilla.org/updates/version-checker;1",
- className: "Version Checker",
- factory: {
- createInstance: function (aOuter, aIID)
- {
- if (aOuter != null)
- throw Components.results.NS_ERROR_NO_AGGREGATION;
-
- return (new nsVersionChecker()).QueryInterface(aIID);
- }
- }
- },
- item: { CID: Components.ID("{F3294B1C-89F4-46F8-98A0-44E1EAE92518}"),
- contractID: "@mozilla.org/updates/item;1",
- className: "Extension Item",
- factory: {
- createInstance: function (aOuter, aIID)
- {
- if (aOuter != null)
- throw Components.results.NS_ERROR_NO_AGGREGATION;
-
- return new UpdateItem().QueryInterface(aIID);
- }
- }
- }
- },
-
- canUnload: function (aComponentManager)
- {
- return true;
- }
- };
-
- function NSGetModule(compMgr, fileSpec)
- {
- return gModule;
- }
-
-