clean up on restart
git-svn-id: svn://10.0.0.236/trunk@175275 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -75,13 +75,17 @@ pref("extensions.logging.enabled", false);
|
||||
// Whether or not app updates are enabled
|
||||
pref("app.update.enabled", false);
|
||||
|
||||
// This preference turns on app.update.mode and allows automatic download and
|
||||
// install to take place. We use a separate boolean toggle for this to make
|
||||
// the UI easier to construct.
|
||||
pref("app.update.auto", true);
|
||||
|
||||
// Defines how the Application Update Service notifies the user about updates:
|
||||
//
|
||||
// AUM Set to: Minor Releases: Major Releases:
|
||||
// 0 download no prompt download no prompt
|
||||
// 1 download no prompt download no prompt if no incompatibilities
|
||||
// 2 download no prompt prompt
|
||||
// 3 prompt prompt
|
||||
//
|
||||
// See chart in nsUpdateService.js.in for more details
|
||||
//
|
||||
|
||||
@@ -101,19 +101,17 @@ var gAdvancedPane = {
|
||||
getService(Components.interfaces.nsIApplicationUpdateService);
|
||||
var checkNowButton = document.getElementById("checkNowButton");
|
||||
checkNowButton.disabled = !aus.canUpdate;
|
||||
|
||||
this.updateAutoInstallUI();
|
||||
|
||||
this.updateAutoPref();
|
||||
return undefined;
|
||||
},
|
||||
|
||||
updateAutoInstallUI: function ()
|
||||
updateAutoPref: function ()
|
||||
{
|
||||
var autoInstallPref = document.getElementById("app.update.autoInstallEnabled");
|
||||
var preference = document.getElementById("app.update.auto");
|
||||
var updateEnabledPref = document.getElementById("app.update.enabled");
|
||||
var ids = ["autoInstallMode", "updateAnd"];
|
||||
var disabled = !updateEnabledPref.value || !autoInstallPref.value;
|
||||
for (var i = 0; i < ids.length; ++i)
|
||||
document.getElementById(ids[i]).disabled = disabled;
|
||||
var autoInstallOptions = document.getElementById("autoInstallOptions");
|
||||
autoInstallOptions.disabled = !preference.value || !updateEnabledPref.value;
|
||||
return undefined;
|
||||
},
|
||||
|
||||
@@ -149,6 +147,12 @@ var gAdvancedPane = {
|
||||
prompter.checkForUpdates(window);
|
||||
},
|
||||
|
||||
showAutoInstallOptions: function ()
|
||||
{
|
||||
document.documentElement.openSubDialog("chrome://browser/content/preferences/update.xul",
|
||||
"", null);
|
||||
},
|
||||
|
||||
showUpdates: function ()
|
||||
{
|
||||
var prompter = Components.classes["@mozilla.org/updates/update-prompt;1"]
|
||||
|
||||
@@ -58,8 +58,7 @@
|
||||
<preference id="general.autoScroll" name="general.autoScroll" type="bool"/>
|
||||
<preference id="general.smoothScroll" name="general.smoothScroll" type="bool"/>
|
||||
<preference id="app.update.enabled" name="app.update.enabled" type="bool"/>
|
||||
<preference id="app.update.autoInstallEnabled" name="app.update.autoInstallEnabled" type="bool"/>
|
||||
<preference id="app.update.mode" name="app.update.mode" type="int"/>
|
||||
<preference id="app.update.auto" name="app.update.auto" type="bool"/>
|
||||
<preference id="extensions.update.autoUpdateEnabled"
|
||||
name="extensions.update.autoUpdateEnabled"
|
||||
type="bool"/>
|
||||
@@ -131,34 +130,23 @@
|
||||
<label>&softwareupdateinfo.label;</label>
|
||||
<separator class="thin"/>
|
||||
<vbox align="start">
|
||||
<checkbox id="enableSmartUpdate"
|
||||
label="&enableSmartUpdate.label;"
|
||||
accesskey="&enableSmartUpdate.accesskey;"
|
||||
<checkbox id="enableAppUpdate"
|
||||
label="&enableAppUpdate.label;"
|
||||
accesskey="&enableAppUpdate.accesskey;"
|
||||
preference="app.update.enabled"
|
||||
onsyncfrompreference="return gAdvancedPane.updateAppUpdateUI();"/>
|
||||
<vbox class="indent" align="start">
|
||||
<checkbox id="enableAutoInstall"
|
||||
label="&enableAutoInstall.label;"
|
||||
accesskey="&enableAutoInstall.accesskey;"
|
||||
preference="app.update.autoInstallEnabled"
|
||||
onsyncfrompreference="return gAdvancedPane.updateAutoInstallUI();"/>
|
||||
<radiogroup id="autoInstallMode" preference="app.update.mode">
|
||||
<grid class="indent">
|
||||
<columns>
|
||||
<column/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row><label id="updateAnd"
|
||||
preference="app.update.enabled">&updateAnd.label;</label>
|
||||
<radio label="&autoDownloadAndInstall.label;"
|
||||
accesskey="&autoDownloadAndInstall.accesskey;" value="0"/></row>
|
||||
<row><hbox/>
|
||||
<radio label="&autoDownloadAndPrompt.label;"
|
||||
accesskey="&autoDownloadAndPrompt.accesskey;" value="1"/></row>
|
||||
</rows>
|
||||
</grid>
|
||||
</radiogroup>
|
||||
<hbox>
|
||||
<checkbox id="enableAutoInstall"
|
||||
label="&enableAutoInstall.label;"
|
||||
accesskey="&enableAutoInstall.accesskey;"
|
||||
preference="app.update.auto"
|
||||
onsyncfrompreference="return gAdvancedPane.updateAutoPref();"/>
|
||||
<spacer flex="1"/>
|
||||
<button id="autoInstallOptions"
|
||||
label="&autoInstallOptions.label;" accesskey="&autoInstallOptions.accesskey;"
|
||||
oncommand="gAdvancedPane.showAutoInstallOptions();"/>
|
||||
</hbox>
|
||||
<separator class="thin"/>
|
||||
<hbox>
|
||||
<button id="checkNowButton"
|
||||
@@ -170,9 +158,7 @@
|
||||
</hbox>
|
||||
</vbox>
|
||||
</vbox>
|
||||
<separator class="thin"/>
|
||||
<separator class="groove"/>
|
||||
<separator class="thin"/>
|
||||
<separator/>
|
||||
<vbox align="start">
|
||||
<checkbox id="enableExtensionUpdate"
|
||||
label="&enableExtensionUpdate.label;"
|
||||
|
||||
@@ -31,3 +31,5 @@ browser.jar:
|
||||
* content/browser/preferences/sanitize.js
|
||||
* content/browser/preferences/tabs.xul
|
||||
* content/browser/preferences/tabs.js
|
||||
* content/browser/preferences/update.xul
|
||||
* content/browser/preferences/update.js
|
||||
|
||||
0
mozilla/browser/components/preferences/update.js
Executable file
0
mozilla/browser/components/preferences/update.js
Executable file
81
mozilla/browser/components/preferences/update.xul
Executable file
81
mozilla/browser/components/preferences/update.xul
Executable file
@@ -0,0 +1,81 @@
|
||||
<?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 Firefox Preferences System.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Google Inc.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2005
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Ben Goodger <ben@mozilla.org> (Original Author)
|
||||
#
|
||||
# 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 *****
|
||||
|
||||
<!DOCTYPE prefwindow [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
%brandDTD;
|
||||
<!ENTITY % updateDTD SYSTEM "chrome://browser/locale/preferences/update.dtd">
|
||||
%updateDTD;
|
||||
]>
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/"?>
|
||||
<?xml-stylesheet href="chrome://mozapps/content/update/updates.css"?>
|
||||
|
||||
<prefwindow id="UpdateSettingsDialog" type="child"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="&update.title;"
|
||||
dlgbuttons="accept,cancel"
|
||||
style="width: &window.width;; height: &window.height;;">
|
||||
|
||||
<prefpane id="UpdateSettingsDialogPane">
|
||||
|
||||
<preferences id="preferences">
|
||||
<preference id="app.update.mode" name="app.update.mode" type="int"/>
|
||||
</preferences>
|
||||
|
||||
<description>&update.intro;</description>
|
||||
<radiogroup id="autoInstallMode" preference="app.update.mode">
|
||||
<hbox>
|
||||
<radio label="&ausMode0Name.label;" accesskey="&ausMode0Name.accesskey;"
|
||||
value="0" flex="1"/>
|
||||
</hbox>
|
||||
<description class="updatePrefsInfo" id="ausMode0Info">&ausMode0Name.info;</description>
|
||||
<hbox>
|
||||
<radio label="&ausMode1Name.label;" accesskey="&ausMode1Name.accesskey;"
|
||||
value="1" flex="1"/>
|
||||
</hbox>
|
||||
<description class="updatePrefsInfo" id="ausMode1Info">&ausMode1Name.info;</description>
|
||||
<radio label="&ausMode2Name.label;" accesskey="&ausMode2Name.accesskey;"
|
||||
value="2"/>
|
||||
<description class="updatePrefsInfo" id="ausMode2Info">&ausMode2Name.info;</description>
|
||||
</radiogroup>
|
||||
<separator/>
|
||||
<separator/>
|
||||
</prefpane>
|
||||
</prefwindow>
|
||||
|
||||
@@ -15,15 +15,13 @@
|
||||
|
||||
<!ENTITY updateTab.label "Update">
|
||||
<!ENTITY softwareupdateinfo.label "Periodically check for updates to:">
|
||||
<!ENTITY enableSmartUpdate.label "&brandShortName;">
|
||||
<!ENTITY enableSmartUpdate.accesskey "F">
|
||||
<!ENTITY enableAutoInstall.label "automatically download updates">
|
||||
<!ENTITY enableAutoInstall.accesskey "d">
|
||||
<!ENTITY updateAnd.label "and:">
|
||||
<!ENTITY autoDownloadAndInstall.label "install them">
|
||||
<!ENTITY autoDownloadAndInstall.accesskey "i">
|
||||
<!ENTITY autoDownloadAndPrompt.label "prompt me when ready to install">
|
||||
<!ENTITY autoDownloadAndPrompt.accesskey "p">
|
||||
<!ENTITY enableAppUpdate.label "&brandShortName;">
|
||||
<!ENTITY enableAppUpdate.accesskey "F">
|
||||
<!ENTITY enableAutoInstall.label "Automatically Download and Install updates">
|
||||
<!ENTITY enableAutoInstall.accesskey "A">
|
||||
<!ENTITY autoInstallOptions.label "Advanced...">
|
||||
<!ENTITY autoInstallOptions.accesskey "d">
|
||||
|
||||
<!ENTITY enableExtensionUpdate.label "My Extensions and Themes">
|
||||
<!ENTITY enableExtensionUpdate.accesskey "x">
|
||||
<!ENTITY checkNow.label "Check Now...">
|
||||
|
||||
22
mozilla/browser/locales/en-US/chrome/browser/preferences/update.dtd
Executable file
22
mozilla/browser/locales/en-US/chrome/browser/preferences/update.dtd
Executable file
@@ -0,0 +1,22 @@
|
||||
<!ENTITY update.title "Automatic Update">
|
||||
<!ENTITY window.width "30em">
|
||||
<!ENTITY window.height "25em">
|
||||
|
||||
<!ENTITY update.intro "Automatically download and install updates for:">
|
||||
|
||||
<!ENTITY ausMode0Name.label "Security/Incremental Updates and New Releases, even if
|
||||
some of my Extensions and Themes will stop working">
|
||||
<!ENTITY ausMode0Name.accesskey "S">
|
||||
<!ENTITY ausMode0Name.info "&brandShortName; will automatically download and install all
|
||||
Updates and New Releases in the background">
|
||||
<!ENTITY ausMode1Name.label "Security/Incremental Updates and New Releases, provided
|
||||
my Extensions and Themes will still work">
|
||||
<!ENTITY ausMode1Name.accesskey "e">
|
||||
<!ENTITY ausMode1Name.info "&brandShortName; will ask your permission before downloading
|
||||
and installing any New Release that will cause some of your
|
||||
Extensions and/or Themes to stop working">
|
||||
<!ENTITY ausMode2Name.label "Security/Incremental Updates only">
|
||||
<!ENTITY ausMode2Name.accesskey "c">
|
||||
<!ENTITY ausMode2Name.info "&brandShortName; will ask your permission before downloading
|
||||
any New Release">
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
locale/browser/preferences/privacy.dtd (%chrome/browser/preferences/privacy.dtd)
|
||||
locale/browser/preferences/sanitize.dtd (%chrome/browser/preferences/sanitize.dtd)
|
||||
locale/browser/preferences/tabs.dtd (%chrome/browser/preferences/tabs.dtd)
|
||||
locale/browser/preferences/update.dtd (%chrome/browser/preferences/update.dtd)
|
||||
locale/browser/sidebar/sidebar.properties (%chrome/browser/sidebar/sidebar.properties)
|
||||
% locale browser-region @AB_CD@ %locale/browser-region/
|
||||
locale/browser-region/region.properties (%chrome/browser-region/region.properties)
|
||||
|
||||
@@ -58,11 +58,11 @@ var gUpdateHistory = {
|
||||
|
||||
for (var i = 0; i < uc; ++i) {
|
||||
var update = um.getUpdateAt(i);
|
||||
if (!update || !update.name)
|
||||
continue;
|
||||
|
||||
var element = document.createElementNS(NS_XUL, "update");
|
||||
this._view.appendChild(element);
|
||||
if (!update.name)
|
||||
continue;
|
||||
element.name = update.name;
|
||||
element.type = bundle.getString("updateType_" + update.type);
|
||||
element.installDate = this._formatDate(update.installDate);
|
||||
|
||||
@@ -189,3 +189,9 @@ update {
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
.updatePrefsInfo {
|
||||
font-size: smaller;
|
||||
margin-left: 27px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
|
||||
@@ -247,22 +247,27 @@ var gUpdates = {
|
||||
* checkForUpdates null -- foreground
|
||||
*/
|
||||
get startPage() {
|
||||
dump("*** GET STARTPAGE\n");
|
||||
if (window.arguments) {
|
||||
var arg0 = window.arguments[0];
|
||||
dump("*** arg0 = " + arg0 + "\n");
|
||||
if (arg0 instanceof Components.interfaces.nsIUpdate) {
|
||||
// If the first argument is a nsIUpdate object, we are notifying the
|
||||
// user that the background checking found an update that requires
|
||||
// their permission to install, and it's ready for download.
|
||||
this.setUpdate(arg0);
|
||||
var p = this.update.selectedPatch;
|
||||
dump("*** P = " + p + "\n");
|
||||
if (p) {
|
||||
switch (p.state) {
|
||||
case STATE_PENDING:
|
||||
this.sourceEvent = SRCEVT_BACKGROUND;
|
||||
return document.getElementById("finishedBackground");
|
||||
case STATE_SUCCEEDED:
|
||||
dump("*** :::::: goats\n");
|
||||
return document.getElementById("installed");
|
||||
case STATE_FAILED:
|
||||
case STATE_APPLYING:
|
||||
return document.getElementById("errors");
|
||||
}
|
||||
}
|
||||
@@ -346,7 +351,8 @@ var gUpdates = {
|
||||
* etc).
|
||||
*/
|
||||
notify: function(timerCallback) {
|
||||
this._prompter[methodName](this._update);
|
||||
if (methodName in this._prompter)
|
||||
this._prompter[methodName](null, this._update);
|
||||
}
|
||||
}
|
||||
tm.registerTimer(timerID, (new Callback(gUpdates.update, methodName)),
|
||||
@@ -596,7 +602,6 @@ var gLicensePage = {
|
||||
nextButton.disabled = true;
|
||||
nextButton.label = gUpdates.strings.getString("IAgreeLabel");
|
||||
gUpdates.wiz.getButton("back").disabled = true;
|
||||
gUpdates.wiz.getButton("next").focus();
|
||||
|
||||
var cancelButton = gUpdates.wiz.getButton("cancel");
|
||||
cancelButton.label = gUpdates.strings.getString("IDoNotAgreeLabel");
|
||||
@@ -612,6 +617,7 @@ var gLicensePage = {
|
||||
// Now that the license text is available, the user is in a position to
|
||||
// agree to it, so enable the Agree button.
|
||||
gUpdates.wiz.getButton("next").disabled = false;
|
||||
gUpdates.wiz.getButton("next").focus();
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -129,6 +129,11 @@ interface nsIUpdate : nsISupports
|
||||
*/
|
||||
attribute AString licenseURL;
|
||||
|
||||
/**
|
||||
* The URL to the Update Service that supplied this update.
|
||||
*/
|
||||
attribute AString serviceURL;
|
||||
|
||||
/**
|
||||
* Whether or not the update being downloaded is a complete replacement of
|
||||
* the user's existing installation or a patch representing the difference
|
||||
@@ -151,6 +156,11 @@ interface nsIUpdate : nsISupports
|
||||
*/
|
||||
readonly attribute nsIUpdatePatch selectedPatch;
|
||||
|
||||
/**
|
||||
* The state of the selected patch.
|
||||
*/
|
||||
attribute AString state;
|
||||
|
||||
/**
|
||||
* The number of patches supplied by this update.
|
||||
*/
|
||||
@@ -372,27 +382,25 @@ interface nsIApplicationUpdateService : nsISupports
|
||||
interface nsIUpdateManager : nsISupports
|
||||
{
|
||||
/**
|
||||
*
|
||||
* Gets the update at the specified index
|
||||
* @param index
|
||||
* The index within the updates array
|
||||
* @returns The nsIUpdate object at the specified index
|
||||
*/
|
||||
nsIUpdate getUpdateAt(in long index);
|
||||
|
||||
/**
|
||||
*
|
||||
* Gets the total number of updates in the history list.
|
||||
*/
|
||||
readonly attribute long updateCount;
|
||||
|
||||
/**
|
||||
*
|
||||
* The active (current) update. The active update is not in the history list.
|
||||
*/
|
||||
attribute nsIUpdate activeUpdate;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void removeUpdateAtIndex(in long index);
|
||||
|
||||
/**
|
||||
*
|
||||
* Saves all updates to disk.
|
||||
*/
|
||||
void saveUpdates();
|
||||
};
|
||||
@@ -400,22 +408,22 @@ interface nsIUpdateManager : nsISupports
|
||||
[scriptable, uuid(0765c92c-6145-4253-9db4-594d8023087e)]
|
||||
interface nsIUpdateTimerManager : nsISupports
|
||||
{
|
||||
/**
|
||||
* Register an interval with the timer manager. The timer manager
|
||||
* periodically checks to see if the interval has expired and if it has
|
||||
* calls the specified callback. This is persistent across application
|
||||
* restarts and can handle intervals of long durations.
|
||||
* @param id
|
||||
* An id that identifies the interval, used for persistence
|
||||
* @param callback
|
||||
* A nsITimerCallback object that is notified when the interval
|
||||
* expires
|
||||
* @param interval
|
||||
* The length of time, in milliseconds, of the interval
|
||||
*/
|
||||
void registerTimer(in AString id,
|
||||
in nsITimerCallback callback,
|
||||
in unsigned long interval);
|
||||
/**
|
||||
* Register an interval with the timer manager. The timer manager
|
||||
* periodically checks to see if the interval has expired and if it has
|
||||
* calls the specified callback. This is persistent across application
|
||||
* restarts and can handle intervals of long durations.
|
||||
* @param id
|
||||
* An id that identifies the interval, used for persistence
|
||||
* @param callback
|
||||
* A nsITimerCallback object that is notified when the interval
|
||||
* expires
|
||||
* @param interval
|
||||
* The length of time, in milliseconds, of the interval
|
||||
*/
|
||||
void registerTimer(in AString id,
|
||||
in nsITimerCallback callback,
|
||||
in unsigned long interval);
|
||||
};
|
||||
|
||||
[scriptable, uuid(22d35700-5765-42e1-914b-a0da7c911a8c)]
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
const PREF_APP_UPDATE_ENABLED = "app.update.enabled";
|
||||
const PREF_APP_UPDATE_AUTO = "app.update.auto";
|
||||
const PREF_APP_UPDATE_MODE = "app.update.mode";
|
||||
const PREF_APP_UPDATE_SILENT = "app.update.silent";
|
||||
const PREF_APP_UPDATE_INTERVAL = "app.update.interval";
|
||||
@@ -482,6 +483,7 @@ UpdatePrompt.prototype = {
|
||||
*/
|
||||
_showUI: function(parent, uri, features, name, update) {
|
||||
var ary = null;
|
||||
dump("*** UUUU = " + update + "\n");
|
||||
if (update) {
|
||||
ary = Components.classes["@mozilla.org/supports-array;1"]
|
||||
.createInstance(Components.interfaces.nsISupportsArray);
|
||||
@@ -536,47 +538,6 @@ function UpdateService() {
|
||||
// Observe xpcom-shutdown to unhook pref branch observers above to avoid
|
||||
// shutdown leaks.
|
||||
gOS.addObserver(this, "xpcom-shutdown", false);
|
||||
|
||||
/*
|
||||
// Detect installation failures and notify
|
||||
var status = readStatusFile(getUpdatesDir());
|
||||
if (status != null) {
|
||||
// null status means the update.status file is not present, because either:
|
||||
// 1) no update was performed, and so there's no UI to show
|
||||
// 2) an update was attempted but failed during checking, transfer or
|
||||
// verification, and was cleaned up at that point, and UI notifying of
|
||||
// that error was shown at that stage.
|
||||
var um =
|
||||
Components.classes["@mozilla.org/updates/update-manager;1"].
|
||||
getService(Components.interfaces.nsIUpdateManager);
|
||||
var prompter =
|
||||
Components.classes["@mozilla.org/updates/update-prompt;1"].
|
||||
createInstance(Components.interfaces.nsIUpdatePrompt);
|
||||
|
||||
var update = um.activeUpdate;
|
||||
if (!update)
|
||||
update = new Update(null);
|
||||
if (status == STATE_SUCCEEDED) {
|
||||
update.statusText = "Install Succeeded";
|
||||
//prompter.showUpdateInstalled(update);
|
||||
}
|
||||
else {
|
||||
// Something went wrong with the patch application process.
|
||||
update.statusText = "goats";
|
||||
// XXXben todo: synthesize the best message
|
||||
//prompter.showUpdateError(update);
|
||||
}
|
||||
|
||||
// Move the update from the Active Update list into the Past Updates list.
|
||||
um.activeUpdate = null;
|
||||
um.saveUpdates();
|
||||
|
||||
// Now trash the updates directory, since we're done with it
|
||||
cleanUpUpdatesDir();
|
||||
}
|
||||
*/
|
||||
|
||||
this._initLoggingPrefs();
|
||||
}
|
||||
|
||||
UpdateService.prototype = {
|
||||
@@ -584,17 +545,13 @@ UpdateService.prototype = {
|
||||
|
||||
observe: function(subject, topic, data) {
|
||||
switch (topic) {
|
||||
case "app-startup":
|
||||
// Resume fetching...
|
||||
var um = Components.classes["@mozilla.org/updates/update-manager;1"]
|
||||
.getService(Components.interfaces.nsIUpdateManager);
|
||||
var activeUpdate = um.activeUpdate;
|
||||
if (activeUpdate)
|
||||
this.downloadUpdate(activeUpdate, true);
|
||||
break;
|
||||
case "profile-after-change":
|
||||
gOS.removeObserver(this, "profile-after-change");
|
||||
|
||||
this._initLoggingPrefs();
|
||||
|
||||
//this._postUpdateCleanup();
|
||||
|
||||
// Register a background update check timer
|
||||
var tm =
|
||||
Components.classes["@mozilla.org/updates/timer-manager;1"]
|
||||
@@ -602,7 +559,13 @@ UpdateService.prototype = {
|
||||
var interval = getPref("getIntPref", PREF_APP_UPDATE_INTERVAL, 86400000);
|
||||
tm.registerTimer("background-update-timer", this, interval);
|
||||
|
||||
this._initLoggingPrefs();
|
||||
// Resume fetching...
|
||||
var um = Components.classes["@mozilla.org/updates/update-manager;1"]
|
||||
.getService(Components.interfaces.nsIUpdateManager);
|
||||
var activeUpdate = um.activeUpdate;
|
||||
if (activeUpdate)
|
||||
this.downloadUpdate(activeUpdate, true);
|
||||
|
||||
break;
|
||||
case "xpcom-shutdown":
|
||||
gOS.removeObserver(this, "xpcom-shutdown");
|
||||
@@ -610,6 +573,55 @@ UpdateService.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
_postUpdateCleanup: function() {
|
||||
// Detect installation failures and notify
|
||||
var status = readStatusFile(getUpdatesDir());
|
||||
if (status != null) {
|
||||
// null status means the update.status file is not present, because either:
|
||||
// 1) no update was performed, and so there's no UI to show
|
||||
// 2) an update was attempted but failed during checking, transfer or
|
||||
// verification, and was cleaned up at that point, and UI notifying of
|
||||
// that error was shown at that stage.
|
||||
var um =
|
||||
Components.classes["@mozilla.org/updates/update-manager;1"].
|
||||
getService(Components.interfaces.nsIUpdateManager);
|
||||
var prompter =
|
||||
Components.classes["@mozilla.org/updates/update-prompt;1"].
|
||||
createInstance(Components.interfaces.nsIUpdatePrompt);
|
||||
|
||||
var update = um.activeUpdate;
|
||||
if (!update)
|
||||
update = new Update(null);
|
||||
update.state = status;
|
||||
if (status == STATE_SUCCEEDED) {
|
||||
update.statusText = "Install Succeeded";
|
||||
LOG("Downloader", "STATE = " + update.selectedPatch.state);
|
||||
LOG("Downloader", "_postUpdateCleanup: Install Succeeded, Showing UI");
|
||||
prompter.showUpdateInstalled(update);
|
||||
}
|
||||
else {
|
||||
// Something went wrong with the patch application process.
|
||||
update.statusText = "goats";
|
||||
// XXXben todo: synthesize the best message
|
||||
LOG("Downloader", "_postUpdateCleanup: Install Failed, Showing UI");
|
||||
prompter.showUpdateError(update);
|
||||
}
|
||||
|
||||
// Move the update from the Active Update list into the Past Updates list.
|
||||
um.activeUpdate = null;
|
||||
um.saveUpdates();
|
||||
|
||||
// Now trash the updates directory, since we're done with it
|
||||
cleanUpUpdatesDir();
|
||||
}
|
||||
else {
|
||||
LOG("Downloader", "_postUpdateCleanup: No Status, No Update");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize Logging preferences, formatted like so:
|
||||
* app.update.log.<moduleName> = <true|false>
|
||||
@@ -704,13 +716,11 @@ UpdateService.prototype = {
|
||||
// Major 1 No Auto Install
|
||||
// Major 1 Yes Notify and Confirm
|
||||
// Major 2 Yes or No Notify and Confirm
|
||||
// Major 3 Yes or No Notify and Confirm
|
||||
// Minor 0 Yes or No Auto Install
|
||||
// Minor 1 No Auto Install
|
||||
// Minor 1 Yes Notify and Confirm
|
||||
// Minor 2 No Auto Install
|
||||
// Minor 2 Yes Notify and Confirm
|
||||
// Minor 3 Yes or No Notify and Confirm
|
||||
//
|
||||
// In addition, if there is a license associated with an update, regardless
|
||||
// of type it must be agreed to.
|
||||
@@ -719,30 +729,49 @@ UpdateService.prototype = {
|
||||
// at all, and so none of the decision making above is entered into.
|
||||
//
|
||||
update.QueryInterface(Components.interfaces.nsIPropertyBag);
|
||||
var licenseAccepted = update.getProperty("licenseAccepted") == "true";
|
||||
if (update.licenseURL && !licenseAccepted)
|
||||
try {
|
||||
var licenseAccepted = update.getProperty("licenseAccepted") == "true";
|
||||
}
|
||||
catch (e) {
|
||||
licenseAccepted = false;
|
||||
}
|
||||
if (update.licenseURL && !licenseAccepted) {
|
||||
LOG("Checker", "_shouldPrompt: Prompting because of an un-accepted " +
|
||||
"license");
|
||||
return true;
|
||||
}
|
||||
|
||||
var updateEnabled = getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true);
|
||||
if (!updateEnabled)
|
||||
if (!updateEnabled) {
|
||||
LOG("Checker", "_shouldPrompt: Not prompting because update is " +
|
||||
"disabled");
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// User has turned off automatic download and install
|
||||
var autoEnabled = getPref("getBoolPref", PREF_APP_UPDATE_AUTO, true);
|
||||
if (!autoEnabled) {
|
||||
LOG("Checker", "_shouldPrompt: Prompting because auto install is disabled");
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (getPref("getIntPref", PREF_APP_UPDATE_MODE, 1)) {
|
||||
case 0:
|
||||
// Mode 0 is do not prompt regardless of incompatibilities
|
||||
return false;
|
||||
case 1:
|
||||
// Mode 1 is do not prompt only if there are no incompatibilities
|
||||
// releases
|
||||
LOG("Checker", "_shouldPrompt: Prompting if there are incompatibilities");
|
||||
return !isCompatible(update);
|
||||
case 2:
|
||||
// Mode 2 is do not prompt only if there are no incompatibilities for
|
||||
// minor updates only
|
||||
if (update.type == "minor")
|
||||
return !isCompatible(update);
|
||||
LOG("Checker", "_shouldPrompt: Prompting if major or there are " +
|
||||
"incompatibilities");
|
||||
return update.type == "minor" ? !isCompatible(update) : true;
|
||||
}
|
||||
// Mode 3 is prompt, regardless.
|
||||
return true;
|
||||
// Mode 0 is do not prompt regardless of incompatibilities
|
||||
LOG("Checker", "_shouldPrompt: Not prompting the user - they choose to " +
|
||||
"ignore incompatibilities");
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -781,6 +810,14 @@ UpdateService.prototype = {
|
||||
* An array of available updates
|
||||
*/
|
||||
_selectAndInstallUpdate: function(updates) {
|
||||
// Don't prompt if there's an active update - the user is already
|
||||
// aware and is downloading, or performed some user action to prevent
|
||||
// notification.
|
||||
var um = Components.classes["@mozilla.org/updates/update-manager;1"]
|
||||
.getService(Components.interfaces.nsIUpdateManager);
|
||||
if (um.activeUpdate)
|
||||
return;
|
||||
|
||||
var update = this.selectUpdate(updates, updates.length);
|
||||
if (!update)
|
||||
return;
|
||||
@@ -789,7 +826,7 @@ UpdateService.prototype = {
|
||||
var prompter =
|
||||
Components.classes["@mozilla.org/updates/update-prompt;1"].
|
||||
createInstance(Components.interfaces.nsIUpdatePrompt);
|
||||
prompter.showUpdateAvailable(update);
|
||||
prompter.showUpdateAvailable(null, update);
|
||||
} else {
|
||||
this.downloadUpdate(update, true);
|
||||
}
|
||||
@@ -900,6 +937,11 @@ UpdateService.prototype = {
|
||||
* @constructor
|
||||
*/
|
||||
function UpdateManager() {
|
||||
// Ensure the Active Update file is loaded
|
||||
var updates = this._loadXMLFileIntoArray(getFile(KEY_APPDIR,
|
||||
[FILE_UPDATE_ACTIVE]));
|
||||
if (updates.length > 0)
|
||||
this._activeUpdate = updates[0];
|
||||
}
|
||||
UpdateManager.prototype = {
|
||||
/**
|
||||
@@ -920,9 +962,11 @@ UpdateManager.prototype = {
|
||||
* @returns The array of nsIUpdate items held in the file.
|
||||
*/
|
||||
_loadXMLFileIntoArray: function(file) {
|
||||
if (!file.exists())
|
||||
if (!file.exists()) {
|
||||
LOG("UpdateManager", "_loadXMLFileIntoArray: XML File does not exist");
|
||||
return [];
|
||||
|
||||
}
|
||||
|
||||
var result = [];
|
||||
var fileStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
|
||||
.createInstance(Components.interfaces.nsIFileInputStream);
|
||||
@@ -949,6 +993,8 @@ UpdateManager.prototype = {
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
LOG("UpdateManager", "_loadXMLFileIntoArray: Error constructing update list " +
|
||||
e);
|
||||
}
|
||||
fileStream.close();
|
||||
return result;
|
||||
@@ -961,21 +1007,8 @@ UpdateManager.prototype = {
|
||||
if (!this._updates)
|
||||
this._updates = this._loadXMLFileIntoArray(getFile(KEY_APPDIR,
|
||||
[FILE_UPDATES_DB]));
|
||||
this._ensureActiveUpdate();
|
||||
},
|
||||
|
||||
/**
|
||||
* Ensure that the Active Update file is loaded.
|
||||
*/
|
||||
_ensureActiveUpdate: function() {
|
||||
if (!this._activeUpdate) {
|
||||
var updates = this._loadXMLFileIntoArray(getFile(KEY_APPDIR,
|
||||
[FILE_UPDATE_ACTIVE]));
|
||||
if (updates.length > 0)
|
||||
this._activeUpdate = updates[0];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIUpdateService.idl
|
||||
*/
|
||||
@@ -996,12 +1029,18 @@ UpdateManager.prototype = {
|
||||
* See nsIUpdateService.idl
|
||||
*/
|
||||
get activeUpdate() {
|
||||
this._ensureActiveUpdate();
|
||||
if (this._activeUpdate &&
|
||||
this._activeUpdate.serviceURL != Checker.prototype.updateURL) {
|
||||
// User switched channels, clear out any old active updates and remove
|
||||
// partial downloads
|
||||
this._activeUpdate = null;
|
||||
|
||||
// Destroy the updates directory, since we're done with it.
|
||||
cleanUpUpdatesDir();
|
||||
}
|
||||
return this._activeUpdate;
|
||||
},
|
||||
set activeUpdate(activeUpdate) {
|
||||
this._ensureActiveUpdate();
|
||||
if (!activeUpdate)
|
||||
this._addUpdate(this._activeUpdate);
|
||||
this._activeUpdate = activeUpdate;
|
||||
if (!activeUpdate) {
|
||||
@@ -1015,14 +1054,6 @@ UpdateManager.prototype = {
|
||||
return activeUpdate;
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIUpdateService.idl
|
||||
*/
|
||||
removeUpdateAtIndex: function(index) {
|
||||
this._ensureUpdates();
|
||||
tihs._updates.splice(index, 1);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add an update to the Updates list. If the item already exists in the list,
|
||||
* replace the existing value with the new value.
|
||||
@@ -1041,7 +1072,8 @@ UpdateManager.prototype = {
|
||||
}
|
||||
}
|
||||
// Otherwise add it to the front of the list.
|
||||
this._updates = [this._activeUpdate].concat(this._updates);
|
||||
if (this._activeUpdate)
|
||||
this._updates = [this._activeUpdate].concat(this._updates);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1133,7 +1165,8 @@ function getPref(func, preference, defaultValue) {
|
||||
*/
|
||||
function UpdatePatch(patch) {
|
||||
for (var i = 0; i < patch.attributes.length; ++i) {
|
||||
var attr = patch.attributes[i];
|
||||
var attr = patch.attributes.item(i);
|
||||
attr.QueryInterface(Components.interfaces.nsIDOMAttr);
|
||||
switch (attr.name) {
|
||||
case "selected":
|
||||
this.selected = attr.value == "true";
|
||||
@@ -1249,19 +1282,14 @@ function Update(update) {
|
||||
}
|
||||
|
||||
for (var i = 0; i < update.attributes.length; ++i) {
|
||||
var attr = update.attributes[i];
|
||||
switch (attr.name) {
|
||||
case "installDate":
|
||||
if (attr.value)
|
||||
this.installDate = parseInt(attr.value);
|
||||
break;
|
||||
case "isCompleteUpdate":
|
||||
var attr = update.attributes.item(i);
|
||||
attr.QueryInterface(Components.interfaces.nsIDOMAttr);
|
||||
if (attr.name == "installDate" && attr.value)
|
||||
this.installDate = parseInt(attr.value);
|
||||
else if (attr.name == "isCompleteUpdate")
|
||||
this.isCompleteUpdate = attr.value == "true";
|
||||
break;
|
||||
default:
|
||||
else
|
||||
this[attr.name] = attr.value;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
// The Update Name is either the string provided by the <update> element, or
|
||||
@@ -1294,7 +1322,27 @@ Update.prototype = {
|
||||
getPatchAt: function(index) {
|
||||
return this._patches[index];
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIUpdateService.idl
|
||||
*/
|
||||
_state: "",
|
||||
set state(state) {
|
||||
if (this.selectedPatch)
|
||||
this.selectedPatch.state = state;
|
||||
else
|
||||
this._state = state;
|
||||
return state;
|
||||
},
|
||||
get state() {
|
||||
if (this.selectedPatch)
|
||||
return this.selectedPatch.state;
|
||||
return this._state;
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIUpdateService.idl
|
||||
*/
|
||||
get selectedPatch() {
|
||||
for (var i = 0; i < this.patchCount; ++i) {
|
||||
if (this._patches[i].selected)
|
||||
@@ -1314,6 +1362,7 @@ Update.prototype = {
|
||||
update.setAttribute("extensionVersion", this.extensionVersion);
|
||||
update.setAttribute("detailsURL", this.detailsURL);
|
||||
update.setAttribute("licenseURL", this.licenseURL);
|
||||
update.setAttribute("serviceURL", this.serviceURL);
|
||||
update.setAttribute("installDate", this.installDate);
|
||||
update.setAttribute("statusText", this.statusText);
|
||||
update.setAttribute("isCompleteUpdate", this.isCompleteUpdate);
|
||||
@@ -1407,7 +1456,7 @@ Checker.prototype = {
|
||||
* The URL of the update service XML file to connect to that contains details
|
||||
* about available updates.
|
||||
*/
|
||||
get _updateURL() {
|
||||
get updateURL() {
|
||||
var url;
|
||||
try {
|
||||
// Use the override URL if specified.
|
||||
@@ -1446,13 +1495,13 @@ Checker.prototype = {
|
||||
if (!listener)
|
||||
throw Components.results.NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (!this._updateURL || (!this.enabled && !force))
|
||||
if (!this.updateURL || (!this.enabled && !force))
|
||||
return;
|
||||
|
||||
this._request =
|
||||
Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].
|
||||
createInstance(Components.interfaces.nsIXMLHttpRequest);
|
||||
this._request.open("GET", this._updateURL, true);
|
||||
this._request.open("GET", this.updateURL, true);
|
||||
this._request.overrideMimeType("text/xml");
|
||||
this._request.setRequestHeader("Cache-Control", "no-cache");
|
||||
|
||||
@@ -1461,7 +1510,7 @@ Checker.prototype = {
|
||||
this._request.onload = function(event) { self.onLoad(event); };
|
||||
this._request.onprogress = function(event) { self.onProgress(event); };
|
||||
|
||||
LOG("Checker", "checkForUpdates: sending request to " + this._updateURL);
|
||||
LOG("Checker", "checkForUpdates: sending request to " + this.updateURL);
|
||||
this._request.send(null);
|
||||
|
||||
this._callback = listener;
|
||||
@@ -1500,7 +1549,10 @@ Checker.prototype = {
|
||||
continue;
|
||||
|
||||
updateElement.QueryInterface(Components.interfaces.nsIDOMElement);
|
||||
updates.push(new Update(updateElement));
|
||||
var update = new Update(updateElement);
|
||||
update.serviceURL = this.updateURL;
|
||||
LOG("Checker", "Creating service URL" + update.serviceURL);
|
||||
updates.push(update);
|
||||
}
|
||||
|
||||
return updates;
|
||||
@@ -1856,12 +1908,16 @@ Downloader.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* An array of download listeners to notify when we receive
|
||||
* nsIRequestObserver or nsIProgressEventSink method calls.
|
||||
*/
|
||||
_listeners: [],
|
||||
|
||||
/**
|
||||
*
|
||||
* Adds a listener to the download process
|
||||
* @param listener
|
||||
* A download listener, implementing nsIRequestObserver and
|
||||
* nsIProgressEventSink
|
||||
*/
|
||||
addDownloadListener: function(listener) {
|
||||
for (var i = 0; i < this._listeners.length; ++i) {
|
||||
@@ -1872,7 +1928,9 @@ Downloader.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* Removes a download listener
|
||||
* @param listener
|
||||
* The listener to remove.
|
||||
*/
|
||||
removeDownloadListener: function(listener) {
|
||||
for (var i = 0; i < this._listeners.length; ++i) {
|
||||
@@ -1884,7 +1942,11 @@ Downloader.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* When the async request begins
|
||||
* @param request
|
||||
* The nsIRequest object for the transfer
|
||||
* @param context
|
||||
* Additional data
|
||||
*/
|
||||
onStartRequest: function(request, context) {
|
||||
request.QueryInterface(nsIIncrementalDownload);
|
||||
@@ -1895,8 +1957,16 @@ Downloader.prototype = {
|
||||
this._listeners[i].onStartRequest(request, context);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
/**
|
||||
* When new data has been downloaded
|
||||
* @param request
|
||||
* The nsIRequest object for the transfer
|
||||
* @param context
|
||||
* Additional data
|
||||
* @param progress
|
||||
* The current number of bytes transferred
|
||||
* @param maxProgress
|
||||
* The total number of bytes that must be transferred
|
||||
*/
|
||||
onProgress: function(request, context, progress, maxProgress) {
|
||||
request.QueryInterface(nsIIncrementalDownload);
|
||||
@@ -1910,8 +1980,16 @@ Downloader.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
/**
|
||||
* When we have new status text
|
||||
* @param request
|
||||
* The nsIRequest object for the transfer
|
||||
* @param context
|
||||
* Additional data
|
||||
* @param status
|
||||
* A status code
|
||||
* @param statusText
|
||||
* Human readable version of |status|
|
||||
*/
|
||||
onStatus: function(request, context, status, statusText) {
|
||||
request.QueryInterface(nsIIncrementalDownload);
|
||||
@@ -1924,8 +2002,14 @@ Downloader.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
/**
|
||||
* When data transfer ceases
|
||||
* @param request
|
||||
* The nsIRequest object for the transfer
|
||||
* @param context
|
||||
* Additional data
|
||||
* @param status
|
||||
* Status code containing the reason for the cessation.
|
||||
*/
|
||||
onStopRequest: function(request, context, status) {
|
||||
request.QueryInterface(nsIIncrementalDownload);
|
||||
@@ -1947,6 +2031,7 @@ Downloader.prototype = {
|
||||
shouldShowPrompt = true;
|
||||
|
||||
// Tell the updater.exe we're ready to apply.
|
||||
dump("*** WRITING STATUS = " + state);
|
||||
this._writeStatusFile(getUpdatesDir(), state);
|
||||
this._update.installDate = (new Date()).getTime();
|
||||
this._update.statusText = "Install Pending";
|
||||
@@ -1995,6 +2080,7 @@ Downloader.prototype = {
|
||||
|
||||
deleteActiveUpdate = true;
|
||||
}
|
||||
LOG("Downloader", "Setting state to: " + state);
|
||||
this._patch.state = state;
|
||||
var um =
|
||||
Components.classes["@mozilla.org/updates/update-manager;1"].
|
||||
@@ -2030,7 +2116,7 @@ Downloader.prototype = {
|
||||
var prompter =
|
||||
Components.classes["@mozilla.org/updates/update-prompt;1"].
|
||||
createInstance(Components.interfaces.nsIUpdatePrompt);
|
||||
prompter.showUpdateDownloaded(this._update);
|
||||
prompter.showUpdateDownloaded(null, this._update);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -2076,6 +2162,7 @@ TimerManager.prototype = {
|
||||
* The checking timer that fired.
|
||||
*/
|
||||
notify: function(timer) {
|
||||
dump("*** STATUS = " + readStatusFile(getUpdatesDir()) + "\n");
|
||||
for (var timerID in this._timers) {
|
||||
var timerData = this._timers[timerID];
|
||||
var lastUpdateTime = timerData.lastUpdateTime;
|
||||
@@ -2209,6 +2296,8 @@ VersionChecker.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
var gUpdateManager = null;
|
||||
|
||||
var gModule = {
|
||||
registerSelf: function(componentManager, fileSpec, location, type) {
|
||||
componentManager = componentManager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
|
||||
@@ -2259,11 +2348,6 @@ var gModule = {
|
||||
className : "Update Checker",
|
||||
factory : #1#(Checker)
|
||||
},
|
||||
manager: { CID : Components.ID("{093C2356-4843-4C65-8709-D7DBCBBE7DFB}"),
|
||||
contractID : "@mozilla.org/updates/update-manager;1",
|
||||
className : "Update Manager",
|
||||
factory : #1#(UpdateManager)
|
||||
},
|
||||
prompt: { CID : Components.ID("{27ABA825-35B5-4018-9FDD-F99250A0E722}"),
|
||||
contractID : "@mozilla.org/updates/update-prompt;1",
|
||||
className : "Update Prompt",
|
||||
@@ -2278,7 +2362,12 @@ var gModule = {
|
||||
contractID : "@mozilla.org/updates/timer-manager;1",
|
||||
className : "Timer Manager",
|
||||
factory : #1#(TimerManager)
|
||||
}
|
||||
},
|
||||
manager: { CID : Components.ID("{093C2356-4843-4C65-8709-D7DBCBBE7DFB}"),
|
||||
contractID : "@mozilla.org/updates/update-manager;1",
|
||||
className : "Update Manager",
|
||||
factory : #1#(UpdateManager)
|
||||
},
|
||||
},
|
||||
|
||||
canUnload: function(componentManager) {
|
||||
|
||||
Reference in New Issue
Block a user