mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 14:25:52 +00:00
Make the update wizard actually invoke XPInstall APIs to install the updates
This commit is contained in:
parent
2194ffe4d2
commit
1b88aad30a
@ -164,6 +164,36 @@ nsExtensionManager.prototype = {
|
||||
// we don't do this every time we start.
|
||||
autoregFile.remove(false);
|
||||
}
|
||||
|
||||
// Load default preferences files for all extensions
|
||||
|
||||
var defaultsManifest = fileLocator.get("ProfD", Components.interfaces.nsIFile);
|
||||
defaultsManifest.append("extensions");
|
||||
defaultsManifest.append("Defaults");
|
||||
if (defaultsManifest.exists()) {
|
||||
var pref = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefService);
|
||||
var fis = Components.classes["@mozilla.org/network/file-input-stream;1"]
|
||||
.createInstance(Components.interfaces.nsIFileInputStream);
|
||||
fis.init(defaultsManifest, -1, -1, false);
|
||||
var lis = fis.QueryInterface(Components.interfaces.nsILineInputStream);
|
||||
var line = { value: "" };
|
||||
var more = false;
|
||||
do {
|
||||
more = lis.readLine(line);
|
||||
var lf = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
var path = line.value;
|
||||
if (path.charAt(path.length-1) == "\n")
|
||||
path = path.substr(0, path.length - 1);
|
||||
lf.initWithPath(path);
|
||||
|
||||
if (lf.exists())
|
||||
pref.readUserPrefs(lf);
|
||||
}
|
||||
while (more);
|
||||
fis.close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -175,7 +205,7 @@ nsExtensionManager.prototype = {
|
||||
// Check to see if the version of the application that is being started
|
||||
// now is the same one that was started last time.
|
||||
var pref = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
var currAppVersion = pref.getCharPref(PREF_EM_APP_VERSION);
|
||||
try {
|
||||
var lastAppVersion = pref.getCharPref(PREF_EM_LAST_APP_VERSION);
|
||||
@ -211,7 +241,7 @@ nsExtensionManager.prototype = {
|
||||
return rv;
|
||||
},
|
||||
|
||||
_writeAutoReg: function ()
|
||||
_writeProfileFile: function (aSubfolder, aFileName, aGetDirFunc, aWriteLineFunc)
|
||||
{
|
||||
// When an operation is performed that requires a component re-registration
|
||||
// (extension enabled/disabled, installed, uninstalled), we must write the
|
||||
@ -230,14 +260,16 @@ nsExtensionManager.prototype = {
|
||||
|
||||
// Open the .autoreg file for writing.
|
||||
|
||||
var autoregFile = profileDir.clone();
|
||||
autoregFile.append(".autoreg");
|
||||
var dataFile = profileDir.clone();
|
||||
if (aSubfolder)
|
||||
dataFile.append(aSubfolder);
|
||||
dataFile.append(aFileName);
|
||||
var fos = Components.classes["@mozilla.org/network/file-output-stream;1"]
|
||||
.createInstance(Components.interfaces.nsIFileOutputStream);
|
||||
const MODE_WRONLY = 0x02;
|
||||
const MODE_CREATE = 0x08;
|
||||
const MODE_TRUNCATE = 0x20;
|
||||
fos.init(autoregFile, MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE, 0664, 0);
|
||||
fos.init(dataFile, MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE, 0664, 0);
|
||||
|
||||
var extensions = this.getItemList(null, Components.interfaces.nsIUpdateItem.TYPE_EXTENSION, { });
|
||||
for (var i = 0; i < extensions.length; ++i) {
|
||||
@ -254,19 +286,60 @@ nsExtensionManager.prototype = {
|
||||
var dir = location == "profile" ? profileDir : globalDir;
|
||||
|
||||
// Now synthesize the components dir for the extension
|
||||
var componentsDir = dir.clone();
|
||||
componentsDir.append("extensions");
|
||||
componentsDir.append(extension.id);
|
||||
componentsDir.append("components");
|
||||
if (componentsDir.exists()) {
|
||||
var sourceDir = aGetDirFunc(dir, extension.id);
|
||||
if (sourceDir.exists()) {
|
||||
// write the relative path of the components dir
|
||||
var line = "reg:extensions/" + extension.id + "/components/\n";
|
||||
fos.write(line, line.length);
|
||||
aWriteLineFunc(fos, sourceDir, extension.id);
|
||||
}
|
||||
}
|
||||
fos.close();
|
||||
},
|
||||
|
||||
_getComponentsDir: function (aSourceDir, aExtensionID)
|
||||
{
|
||||
var sourceDir = aSourceDir.clone();
|
||||
sourceDir.append("extensions");
|
||||
sourceDir.append(aExtensionID);
|
||||
sourceDir.append("components");
|
||||
return sourceDir;
|
||||
},
|
||||
|
||||
_getPreferencesDir: function (aSourceDir, aExtensionID)
|
||||
{
|
||||
var sourceDir = aSourceDir.clone();
|
||||
sourceDir.append("extensions");
|
||||
sourceDir.append(aExtensionID);
|
||||
sourceDir.append("defaults");
|
||||
sourceDir.append("preferences");
|
||||
return sourceDir;
|
||||
},
|
||||
|
||||
_writeAutoregLines: function (aStream, aSourceDir, aExtensionID)
|
||||
{
|
||||
var line = "reg:extensions/" + aExtensionID + "/components/\n";
|
||||
aStream.write(line, line.length);
|
||||
},
|
||||
|
||||
_writePreferencesLines: function (aStream, aSourceDir, aExtensionID)
|
||||
{
|
||||
var files = aSourceDir.directoryEntries;
|
||||
while (files.hasMoreElements()) {
|
||||
var file = files.getNext().QueryInterface(Components.interfaces.nsILocalFile);
|
||||
var line = file.path + "\n";
|
||||
aStream.write(line, line.length);
|
||||
}
|
||||
},
|
||||
|
||||
_writeProfileData: function ()
|
||||
{
|
||||
this._writeProfileFile(null, ".autoreg",
|
||||
this._getComponentsDir,
|
||||
this._writeAutoregLines);
|
||||
this._writeProfileFile("extensions", "Defaults",
|
||||
this._getPreferencesDir,
|
||||
this._writePreferencesLines);
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsIExtensionManager
|
||||
installExtensionFromStream: function (aStream, aUseProfile)
|
||||
@ -290,25 +363,25 @@ nsExtensionManager.prototype = {
|
||||
this._ensureDS();
|
||||
|
||||
this._ds.installExtension(ds, aUseProfile);
|
||||
this._writeAutoReg();
|
||||
this._writeProfileData();
|
||||
},
|
||||
|
||||
uninstallExtension: function (aExtensionID)
|
||||
{
|
||||
this._ds.uninstallExtension(aExtensionID);
|
||||
this._writeAutoReg();
|
||||
this._writeProfileData();
|
||||
},
|
||||
|
||||
enableExtension: function (aExtensionID)
|
||||
{
|
||||
this._ds.enableExtension(aExtensionID);
|
||||
this._writeAutoReg();
|
||||
this._writeProfileData();
|
||||
},
|
||||
|
||||
disableExtension: function (aExtensionID)
|
||||
{
|
||||
this._ds.disableExtension(aExtensionID);
|
||||
this._writeAutoReg();
|
||||
this._writeProfileData();
|
||||
},
|
||||
|
||||
// XXXben - handle the case where the item provides its own update url.
|
||||
|
@ -23,6 +23,7 @@ toolkit.jar:
|
||||
* content/mozapps/update/update.js (update/content/update.js)
|
||||
* content/mozapps/update/updates.xml (update/content/updates.xml)
|
||||
* content/mozapps/update/update.css (update/content/update.css)
|
||||
* content/mozapps/update/errors.xul (update/content/errors.xul)
|
||||
* content/mozapps/shared/richview.xml (shared/content/richview.xml)
|
||||
content/mozapps/contents.rdf (contents-content.rdf)
|
||||
|
||||
@ -39,6 +40,7 @@ en-US.jar:
|
||||
locale/en-US/mozapps/extensions/about.dtd (extensions/locale/about.dtd)
|
||||
locale/en-US/mozapps/update/update.dtd (update/locale/update.dtd)
|
||||
locale/en-US/mozapps/update/update.properties (update/locale/update.properties)
|
||||
locale/en-US/mozapps/update/errors.dtd (update/locale/errors.dtd)
|
||||
locale/en-US/mozapps/contents.rdf (contents-locale.rdf)
|
||||
|
||||
classic.jar:
|
||||
|
81
toolkit/mozapps/update/content/errors.xul
Normal file
81
toolkit/mozapps/update/content/errors.xul
Normal 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 Update Service.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Ben Goodger.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2004
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Ben Goodger <ben@bengoodger.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
||||
<!DOCTYPE dialog SYSTEM "chrome://mozapps/locale/update/errors.dtd">
|
||||
|
||||
<dialog id="errors"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="&errors.title;"
|
||||
onload="init()"
|
||||
style="width: 25em;"
|
||||
buttons="cancel">
|
||||
|
||||
<script type="application/x-javascript">
|
||||
<![CDATA[
|
||||
function init()
|
||||
{
|
||||
var items = window.arguments[0];
|
||||
var listbox = document.getElementById("extensions");
|
||||
for (var i = 0; i < items.length; ++i) {
|
||||
if (items[i].error) {
|
||||
var listitem = document.createElement("listitem");
|
||||
listitem.setAttribute("label", items[i].name);
|
||||
listbox.appendChild(listitem);
|
||||
}
|
||||
}
|
||||
var strings = document.getElementById("updateStrings");
|
||||
var cancel = document.documentElement.getButton("cancel");
|
||||
cancel.label = strings.getString("closeButton");
|
||||
cancel.focus();
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<stringbundleset id="updateSet">
|
||||
<stringbundle id="updateStrings" src="chrome://mozapps/locale/update/update.properties"/>
|
||||
</stringbundleset>
|
||||
|
||||
<label>&errors.intro.title;</label>
|
||||
<separator/>
|
||||
<listbox id="extensions" rows="7"/>
|
||||
<separator/>
|
||||
|
||||
</dialog>
|
||||
|
@ -368,14 +368,69 @@ var gInstallingPage = {
|
||||
|
||||
// Get XPInstallManager and kick off download/install
|
||||
// process, registering us as an observer.
|
||||
var items = [];
|
||||
|
||||
//XXXben
|
||||
window.advance = function()
|
||||
{
|
||||
document.getElementById("installing").setAttribute("next", "finished");
|
||||
document.documentElement.advance();
|
||||
var foundList = document.getElementById("foundList");
|
||||
for (var i = 0; i < foundList.childNodes.length; ++i) {
|
||||
var item = foundList.childNodes[i];
|
||||
if (item.type != nsIUpdateItem.TYPE_APP) {
|
||||
items.push(item.url);
|
||||
this._objs.push({ name: item.name });
|
||||
}
|
||||
}
|
||||
setTimeout("advance()", 2000);
|
||||
|
||||
var xpimgr = Components.classes["@mozilla.org/xpinstall/install-manager;1"]
|
||||
.createInstance(Components.interfaces.nsIXPInstallManager);
|
||||
xpimgr.initManagerFromChrome(items, items.length, this);
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsIXPIProgressDialog
|
||||
onStateChange: function (aIndex, aState, aValue)
|
||||
{
|
||||
var strings = document.getElementById("updateStrings");
|
||||
|
||||
const nsIXPIProgressDialog = Components.interfaces.nsIXPIProgressDialog;
|
||||
switch (aState) {
|
||||
case nsIXPIProgressDialog.DOWNLOAD_START:
|
||||
var label = strings.getFormattedString("downloadingPrefix", [this._objs[aIndex].name]);
|
||||
var actionItem = document.getElementById("actionItem");
|
||||
actionItem.value = label;
|
||||
break;
|
||||
case nsIXPIProgressDialog.DOWNLOAD_DONE:
|
||||
case nsIXPIProgressDialog.INSTALL_START:
|
||||
var label = strings.getFormattedString("installingPrefix", [this._objs[aIndex].name]);
|
||||
var actionItem = document.getElementById("actionItem");
|
||||
actionItem.value = label;
|
||||
break;
|
||||
case nsIXPIProgressDialog.INSTALL_DONE:
|
||||
if (aValue) {
|
||||
this._objs[aIndex].error = aValue;
|
||||
this._errors = true;
|
||||
}
|
||||
break;
|
||||
case nsIXPIProgressDialog.DIALOG_CLOSE:
|
||||
document.getElementById("installing").setAttribute("next", this._errors ? "errors" : "finished");
|
||||
document.documentElement.advance();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_objs: [],
|
||||
_errors: false,
|
||||
|
||||
onProgress: function (aIndex, aValue, aMaxValue)
|
||||
{
|
||||
var downloadProgress = document.getElementById("downloadProgress");
|
||||
downloadProgress.value = Math.ceil((aValue/aMaxValue) * 100);
|
||||
}
|
||||
};
|
||||
|
||||
var gErrorsPage = {
|
||||
onShowErrors: function ()
|
||||
{
|
||||
openDialog("chrome://mozapps/content/update/errors.xul", "",
|
||||
"modal", gInstallingPage._objs);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -131,10 +131,20 @@
|
||||
label="&installing.title;"
|
||||
onpageshow="gInstallingPage.onPageShow();">
|
||||
<label>&installing.intro.label;</label>
|
||||
<label>&installing.disclaimer.label;</label>
|
||||
<label id="actionItem"/>
|
||||
<progressmeter id="downloadProgress"/>
|
||||
|
||||
<separator/>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="errors" pageid="errors"
|
||||
label="&errors.title;"
|
||||
align="right">
|
||||
<label>&errors.intro.label;</label>
|
||||
<separator/>
|
||||
<button label="&errors.details.label;" accesskey="&errors.details.accesskey;"
|
||||
oncommand="gErrorsPage.onShowErrors();"/>
|
||||
<separator/>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="finished" pageid="finished"
|
||||
|
@ -24,6 +24,7 @@
|
||||
var os = Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Components.interfaces.nsIObserverService);
|
||||
os.addObserver(this, "Update:Ended", false);
|
||||
this.refreshData("null");
|
||||
]]>
|
||||
</constructor>
|
||||
<destructor>
|
||||
@ -41,18 +42,24 @@
|
||||
<parameter name="aData"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (aTopic == "Update:Ended") {
|
||||
if (aTopic == "Update:Ended")
|
||||
this.refreshData(Components.interfaces.nsIUpdateService.SOURCE_EVENT_BACKGROUND);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="refreshData">
|
||||
<parameter name="aSourceEvent"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var updates = Components.classes["@mozilla.org/updates/update-service;1"]
|
||||
.getService(Components.interfaces.nsIUpdateService);
|
||||
this.severity = updates.updateSeverity;
|
||||
this.updateCount = updates.updateCount;
|
||||
delete updates;
|
||||
updates = null;
|
||||
#ifdef XP_WIN
|
||||
if (parseInt(aData) == Components.interfaces.nsIUpdateService.SOURCE_EVENT_BACKGROUND)
|
||||
if (parseInt(aSourceEvent) == Components.interfaces.nsIUpdateService.SOURCE_EVENT_BACKGROUND)
|
||||
this._showUpdateInfo();
|
||||
#endif
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
5
toolkit/mozapps/update/locale/errors.dtd
Normal file
5
toolkit/mozapps/update/locale/errors.dtd
Normal file
@ -0,0 +1,5 @@
|
||||
<!ENTITY errors.title "Errors">
|
||||
<!ENTITY errors.intro.title "The following components could not be installed due to errors
|
||||
(the file could not be downloaded, was corrupt, or for some
|
||||
other reason).">
|
||||
|
@ -1,12 +1,12 @@
|
||||
<!ENTITY updateWizard.title "&brandShortName; Update">
|
||||
|
||||
<!ENTITY mismatch.title "Incompatible Extensions">
|
||||
<!ENTITY mismatch.intro1.label "The following extensions are not compatible with the new version
|
||||
<!ENTITY mismatch.title "Incompatible Components">
|
||||
<!ENTITY mismatch.intro1.label "The following components are not compatible with the new version
|
||||
of &brandShortName; you have just installed:">
|
||||
<!ENTITY mismatch.intro2.label "They have been disabled until compatible versions are
|
||||
installed.">
|
||||
<!ENTITY mismatch.intro3.label "&brandShortName; can check for and install newer, compatible
|
||||
versions of these extensions.">
|
||||
versions of these components.">
|
||||
|
||||
<!ENTITY checking.title "Checking for Updates">
|
||||
<!ENTITY checking.intro.label "&brandShortName; is now checking for available updates...">
|
||||
@ -37,14 +37,16 @@
|
||||
|
||||
<!ENTITY finished.title "Update Complete">
|
||||
<!ENTITY finished.updated.label "&brandShortName; has installed the available updates.">
|
||||
<!ENTITY finished.remaining.label "Some incompatible extensions could not be updated, perhaps
|
||||
<!ENTITY finished.remaining.label "Some incompatible components could not be updated, perhaps
|
||||
because compatible versions are not available at this time.
|
||||
&brandShortName; will check periodically and inform you
|
||||
when updated versions become available.">
|
||||
<!ENTITY finished.remaining2.label "Some incompatible extensions could not be updated, perhaps
|
||||
<!ENTITY finished.remaining2.label "Some incompatible components could not be updated, perhaps
|
||||
because compatible versions are not available at this time.
|
||||
&brandShortName; can check periodically and inform you
|
||||
when updated versions become available.">
|
||||
<!ENTITY finished.error.label "&brandShortName; did not succeed in downloading and
|
||||
installing some updates.">
|
||||
<!ENTITY finished.enableChecking.label "Allow &brandShortName; to check for updates.">
|
||||
<!ENTITY finished.mismatch.label "Click Finish to continue starting &brandShortName;.">
|
||||
|
||||
@ -55,5 +57,9 @@
|
||||
web site where you can download the latest version of
|
||||
&brandShortName;.">
|
||||
|
||||
|
||||
<!ENTITY errors.title "Problems During Update">
|
||||
<!ENTITY errors.intro.label "&brandShortName; encountered problems when updating your
|
||||
software, and as a result not all components could be updated.">
|
||||
<!ENTITY errors.details.label "Details">
|
||||
<!ENTITY errors.details.accesskey "D">
|
||||
|
||||
|
@ -10,3 +10,7 @@ update.app.url=http://localhost/update.rdf
|
||||
|
||||
updatesAvailableTitle=New Updates Available
|
||||
updatesAvailableText=Click Here to View
|
||||
|
||||
downloadingPrefix=Downloading: %S
|
||||
installingPrefix=Installing: %S
|
||||
closeButton=Close
|
||||
|
@ -94,9 +94,6 @@ nsBackgroundUpdateService.prototype = {
|
||||
var interval = this._pref.getIntPref(PREF_UPDATE_INTERVAL);
|
||||
var lastUpdateTime = this._pref.getIntPref(PREF_UPDATE_LASTUPDATEDATE);
|
||||
var timeSinceLastCheck = Date.UTC() - lastUpdateTime;
|
||||
this.checkForUpdatesInternal([], 0, nsIUpdateItem.TYPE_ANY,
|
||||
nsIUpdateService.SOURCE_EVENT_BACKGROUND); /// XXXben
|
||||
|
||||
if (timeSinceLastCheck > interval) {
|
||||
if (!this.updating)
|
||||
this.checkForUpdatesInternal([], 0, nsIUpdateItem.TYPE_ANY,
|
||||
|
Loading…
Reference in New Issue
Block a user